1. 程式人生 > >系統技術非業餘研究 » 對try 異常 執行的疑問,為什麼出現兩種結果

系統技術非業餘研究 » 對try 異常 執行的疑問,為什麼出現兩種結果

郎鹹武<[email protected]>  同學在erlang-china上post了一個問題:
請注意編號為91和92兩行執行結果,請問為什麼會出現兩種結果。
一個丟擲 {error,{badmatch,5}}
另一個丟擲** exception error: no match of right hand side value 4

[email protected]:/usr/src/otp# erl
Erlang R13B04 (erts-5.7.5) [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false
88> X=1.
1
89> try (X=5) of Val ->{normal,Val} catch error:Error -> {error,Error}  end.
{error,{badmatch,5}}
90> try (X=1) of Val ->{normal,Val} catch error:Error -> {error,Error}  end.
{normal,1}
91> try (X=5) of Val ->{normal,Val} catch error:Error -> {error,Error}  end.
{error,{badmatch,5}}
92> try (X=4) of Val ->{normal,Val} catch error:Error -> {error,Error}  end.
** exception error: no match of right hand side value 4
93> self().
<0.36.0>
94> catch try (X=4) of Val  ->{normal,Val} catch error:Error -> {error,Error}  end. %%這個異常是 shell捕獲到了 進一步處理後的結果
{'EXIT',{{badmatch,4},[{erl_eval,expr,3}]}}
95> try (X=4) of Val ->{normal,Val} catch error:Error ->  {error,Error}  end.
** exception error: no match of right hand  side value 4
96> self().
<0.36.0>

竟然是EXIT, 這時候shell也換了pid了, 這是怎麼回事呢?
由於在shell輸入的程式是公司允許的, 我們也可以從出錯的stack裡面看到是 erl_eval:expr函式異常了.
現在讓我們對系統打patch如下:
lib/stdlib/src/erl_eval.erl

 282expr({match,_,Lhs,Rhs0},  Bs0, Lf, Ef, RBs) ->
 283    {value,Rhs,Bs1} = expr(Rhs0, Bs0,  Lf, Ef, none),
 284    case match(Lhs, Rhs, Bs1) of
 285         {match,Bs} ->
 286            ret_expr(Rhs, Bs, RBs);
 287        nomatch ->
 288            io:format("expr nomatch->pid:~p~n~p~n",[self(), Rhs]),   %%新增診斷
 289             erlang:raise(error, {badmatch,Rhs}, stacktrace())
 290    end;

erts/emulator/beam/bif.c

1142/**********************************************************************/
1143/*  raise an exception of given class, value and  stacktrace.
1144  *
1145 * If there is an error in the argument  format,
1146 * return the atom 'badarg'  instead.
1147 */
1148Eterm
1149raise_3(Process *c_p, Eterm class,  Eterm value, Eterm stacktrace) {
...
1222     erts_print(ERTS_PRINT_STDOUT, NULL, "raise->proc:%T\nclass=%T\nvalue=%T\nstacktrace=%T\n", c_p->id, class, value,  c_p->ftrace); /*新增診斷*/
1223    BIF_ERROR(c_p, reason);
...
}

然 後我們在執行上面的語句:

[email protected]:~/otp#  bin/erl
Erlang R13B04 (erts-5.7.5)   [smp:2:2] [rq:2]  [async-threads:0] [kernel-poll:false]

Eshell  V5.7.5  (abort with  ^G)
1> X=1.
 1
2>  try (X=5) of Val ->{normal,Val}  catch error:Error ->  {error,Error}  end.
expr nomatch->pid:<0.32.0>
5
raise->proc:<0.32.0>
class=error
value={badmatch,5}
stacktrace=[[{erl_eval,expr,3}
{error,{badmatch,5}}
3>  try  (X=4) of Val ->{normal,Val} catch  error:Error -> {error,Error}   end.
expr nomatch->pid:<0.32.0>
4
raise->proc:<0.32.0>
class=error
value={badmatch,4}
stacktrace=[[{erl_eval,expr,3}]|-000000000000000016]
raise->proc:<0.32.0>
class=error
value={badmatch,4}
stacktrace=[[{erl_eval,expr,3}]|-000000000000000016]

很奇怪的是第3句raise了2次. 讓我們回到程式好好看下:

X=1.   %%這行綁定了一個變數X=1
try (X=5) of Val ->{normal,Val} catch  error:Error -> {error,Error}  end.   %%這行由於異常會試圖繫結變數Error={badmatch,5}, 由於之前Error不存在, 繫結成功.
try  (X=4) of Val ->{normal,Val} catch error:Error -> {error,Error}   end.   %%這行由於異常會綁定了變數Error={badmatch,4}, 由於Error存在,  而且值是{badmatch,5},所以這時候catch就出
現異常了,  往外丟擲{'EXIT',{{badmatch,4},[{erl_eval,expr,3}]}}.

這 下我們明白了, 是這個catch惹的禍了.
我們再實驗下我們的分析:

[email protected]:~#  erl
Erlang R13B04 (erts-5.7.5)  [smp:2:2] [rq:2]  [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.5   (abort with ^G)
1> X=1.
1
2> b().
X = 1
ok
3>  try (X=5) of Val ->{normal,Val} catch error:Error ->  {error,Error}  end.
{error,{badmatch,5}}
4> b().
Error =  {badmatch,5}
X = 1
ok
5> try (X=4) of Val ->{normal,Val}  catch error:Error -> {error,Error}  end.
** exception error: no  match of right hand side value 4
6> f(Error).
ok
7>  b().
X = 1
ok
8> try (X=4) of Val ->{normal,Val}  catch error:Error -> {error,Error}  end.
{error,{badmatch,4}}
9>

Bingo成功.
結論: 要非常小心Erlang語法的變數繫結,在不同的路線會有不同的繫結,容易出問題.

Post Footer automatically generated by wp-posturl plugin for wordpress.

相關推薦

系統技術業餘研究 » try 異常 執行疑問為什麼出現結果

郎鹹武<[email protected]>  同學在erlang-china上post了一個問題: 請注意編號為91和92兩行執行結果,請問為什麼會出現兩種結果。 一個丟擲 {error,{badmatch,5}} 另一個丟擲** exception error: no m

系統技術業餘研究 » Erlang R15的記憶體delayed dealloc特性訊息密集型程式的影響

在新的NUMA體系結構下,每個CPU都有自己的本地記憶體,如果要訪問其他CPU的記憶體,那算remote了,要走CPU之間的QPI通道,通常這樣速度會有40%的下降。 那麼對於多執行緒的程式來講,這個硬體的變化對軟體也有很大的影響。在多執行緒程式裡面,通常一個執行緒會為一個物件分配記憶體,然後把這

系統技術業餘研究 » Linux檔案預讀分析以及評估系統的影響

Linux系統很重要的一個性能提升點就是它的Pagecache, 因為記憶體比IO快太多了,所以大家都想進辦法來利用這個cache。 檔案系統也不例外,為了達到高效能,檔案讀取通常採用預讀來預測使用者的行為,把使用者可能需要的資料預先讀取到cache去,達到高效能的目的。 Linux各個發行版re

系統技術業餘研究 » 突破systemtap指令碼資源使用的限制

我們在使用指令碼收集系統資訊的時候經常會用到map這樣的資料結構存放結果,但是stap指令碼在使用過程中經常會提升說”ERROR: Array overflow, check MAXMAPENTRIES near identifier ‘a’ at test.stp:6:5″ 類似這樣的資訊,然後

系統技術業餘研究 » 實驗Erlang語法對應的opcode 讓你erlang理解更深

Erlang作為一門FP語言,和傳統的語言結構一樣, 有模組, 有函式, 有語句, 有判斷, 有迴圈, 還有特別的模式匹配。 那麼這些在底層是如何運作的。 我在底下給大家做個簡單的實驗,讓大家一窺內部的細節,讓大家寫碼的時候知道個大概。 erlang的VM作為register based的VM,

系統技術業餘研究 » Systemtap輔助設定tcp_init_cwnd,免作業系統打Patch

前段時間google的工程師提出對tcp的擁塞視窗的初始值進行增大可以顯著的提高http的效能,這個主要是針對tcp的slow start的優化. 具體參考這裡, 這裡. 謝謝叔度同學從美國帶回第一手資訊! 由於低版本的linux核心的問題,這個引數的正確設定需要對os打patch,這個過程對線

系統技術業餘研究 » 如何找出異常所在的行(新思路)

在Erlang-china的郵件列表上看到這樣的問題: 我的服務經常發生這樣的錯誤,舉例: Error in process <0.33.0> with exit value: {badarg,[{erlang,’++’,[undefined,[{“37”}]]},{groups,do

系統技術業餘研究 » Erlang如何限制節點叢集的訪問之net_kernel:allow

預設情況下Erlang的叢集訪問是全授權的,只要cookie認證過了後,新加入的節點可以訪問叢集裡面的任何機器,這給運維帶來很大風險。目前erlang有二種方法可以限制 1. IP網段限制,參看這裡 2. 節點名稱限制。這個是通過net_kernel:allow來實現的,參看: allow/1 L

系統技術業餘研究

ItPub寫的文章“2017 年度 DB-Engines 資料庫冠軍得主:PostgreSQL 封王!”, 點選 這裡 進一步閱讀 升的最快的幾個資料庫,我簡單的無責任點評: PG資料庫是很老的資料庫,不過這幾年冉冉升起,因為是學院派的,有很好的學術和智力的支援,一直以來在資料庫的體系結構,程式碼

系統技術業餘研究 » MySQL資料庫架構的演化觀察

MySQL資料庫架構的演化觀察 December 14th, 2017 Categories: 資料庫 Tags: mysql

系統技術業餘研究 » inet_dist_connect_options

Erlang 17.5版本引入了inet_dist_{listen,connect}_options,對於結點間的互聯socket可以有更精細的控制,RPC的時候效能可以微調: raimo/inet_tcp_dist-priority-option/OTP-12476: Document ke

系統技術業餘研究 » 推薦工作機會

最後更新時間:2014/11/28 請賜簡歷至:[email protected], 感謝您對加入我們公司有興趣,我們希望能早日和您共事。 以下幾個職位1年內有效,歡迎內部轉崗:
 資深資料工程師 公司:阿里(核心系統資料庫組) 工作地點:杭州(西溪園區) 崗位描述: 分析雲服務產生的海

系統技術業餘研究 » 新的工作和研究方向

和大家更新下: 做了將近8年資料庫後,我的工作和研究方向將會延伸到虛擬化和計算相關的雲服務,希望能夠和大家一起進步,Happy New Year! 預祝大家玩得開心! Post Footer automatically generated by wp-posturl plugin for w

系統技術業餘研究 » 叢集引入inet_dist_{listen,connect}_options更精細引數微調

Erlang 17.5版本引入了inet_dist_{listen,connect}_options,對於結點間的互聯socket可以有更精細的控制,RPC的時候效能可以微調: raimo/inet_tcp_dist-priority-option/OTP-12476: Document ke

系統技術業餘研究 » 2017升的最快的幾個資料庫無責任點評

ItPub寫的文章“2017 年度 DB-Engines 資料庫冠軍得主:PostgreSQL 封王!”, 點選 這裡 進一步閱讀 升的最快的幾個資料庫,我簡單的無責任點評: PG資料庫是很老的資料庫,不過這幾年冉冉升起,因為是學院派的,有很好的學術和智力的支援,一直以來在資料庫的體系結構,程式碼

系統技術業餘研究 » Erlang 17.5引入+hpds命令列控制程序預設字典大小

Erlang 17.5釋出引入控制程序預設字典大小的命令列引數: Erlang/OTP 17.5 has been released Written by Henrik, 01 Apr 2015 Some highlights of the release are: ERTS: Added co

系統技術業餘研究 » inet_dist_listen_options

Erlang 17.5版本引入了inet_dist_{listen,connect}_options,對於結點間的互聯socket可以有更精細的控制,RPC的時候效能可以微調: raimo/inet_tcp_dist-priority-option/OTP-12476: Document ke

系統技術業餘研究 » 老生常談: ulimit問題及其影響

ulimit最初設計是用來限制程序對資源的使用情況的,因為早期的系統系統資源包括記憶體,CPU都是非常有限的,系統要保持公平,就要限制大家的使用,以達到一個相對公平的環境。以下是典型的機器預設的限制情況: $ ulimit -a core file size (blocks,

系統技術業餘研究 » 求賢帖

原創文章,轉載請註明: 轉載自系統技術非業餘研究 本文連結地址: 求賢帖 作為一個優秀的工程師,你其實不缺少才華,你缺少的是神一樣的隊友、充滿挑戰的世界級技術難題,和一個可以施展自己才華的大舞臺。加入阿里核心系統資料庫開發團隊吧,你缺的這裡都有。來吧,戳這裡,給我們見識你的機會:http://b

系統技術業餘研究 » Erlang R16B03釋出R17已發力

Erlang R16B03釋出了,通常03版本是bug fix版本,進入生產版本,官方的說明如下: OTP R16B03 is a service release with mostly a number of small corrections and user contributions. B