[erlang-questions] Fwd: How to read process's backtrace data?

skyman cloudzen@REDACTED
Sun Nov 18 13:08:13 CET 2012


Thank you very much, Raimo. I'll try it later.


At 2012-11-15 17:19:46,"Raimo Niskanen" <raimo+erlang-questions@REDACTED> wrote:
>On Wed, Nov 14, 2012 at 11:26:38PM +0800, skyman wrote:
>> Hi erlang developers,
>> Can anyone answer this question please? Thanks in advance.
>
>Since there are no other takers; I hope my memory does not make me
>flunk misarably...
>
>"Program counter" is of course the program counter. It points
>to the next VM instruction to be executed. This one is fetched from
>the process structure and is a copy that is stored when the process
>is scheduled out, for example. So it is not always correct.
>
>"CP" is the continuation pointer. That is the next return address
>to use by a return instruction. This is a VM register so for small
>functions it does not have to be pushed on the stack, but if
>another call is made the old value has to be pushed. This causes
>the "Return addr" values in the stack trace to be "delayed"
>or off by one stack frame. You'll see shortly.
>
>y(n) is the VM notation for the 'y' register array, which is
>on the stack, for the current stack frame.
>
>So, we begin at the bottom, which is chronological order.
>To understand fully we need the assembly listing of the code...
>y(1) and y(0) has values - two values were pushed to the stack,
>then a Return addr. This is to a special internal function
>that every process originates from. When the process returns
>here you can guess what happens <terminate process normally>.
>
>The function related to these pushes is the next return addres
>above, since a return address first is stored in CP and not
>until the next call it is pushed on the stack. In this
>case it is shell:eval_loop/3+308. 308 is the assembly code
>offset after the entry point. So shell:eval_loop/3 pushes
>a pid() and an integer() to the stack before calling...
>next return address on the stack is shell:eval_exprs/7+80.
>
>Looking at shell:eval_loop/3 shows that it indeed calls
>shell:eval_exprs/7 and that there are two variables
>that have to survive the call i.e Shell and RT.
>These are probably a pid and an ets table id (pid()
>and integer()).
>
>Next stack frame. 6 variables are pushed, the first
>is a Catch to shell:eval_exprs/7+196. We are now in
>shell:eval_exprs/7 and it calls shell:exprs/6 within
>a try..catch. So the VM pushes a Catch and all
>the variables that need to survive to catch clause
>aparently Shell and 4 empty lists and then calls shell:exprs/6.
>
>Next return address is shell:exprs/7+368. Looking at the code
>for shell:exprs/6 shows that it tail recursevly calls
>shell:exprs/7 so that is why there is no return address
>of shell:exprs/6 on the stack. There were 10 variables
>pushed on the stack before the next call, and we were in
>shell:exprs/7. The next return address is the CP itself
>and it is erl_eval:do_apply/6+208.
>
>Looking at the code of shell:exprs/7 shows that it calls
>shell:expr/4, which tail recursively calls erl_eval:expr/4,
>which tail recursively calls erl_eval:expr/5, which tail
>recursively calls erl_eval:do_apply/6, so that is how
>we get there. That function (erl_eval:do_apply/6) apparently
>has pushed two variables on the stack, [] and 'none'
>before calling somewhere and storing itself in CP.
>Looking at the code shows that it calls apply(Mod, Func, As)
>wich is a BIF or an instruction, which probably accounts
>for the strange Program counter. After it has returned
>it will need Bs0 and RBs, which probably are the [] and 'none'
>values in some order. To know we need the assembly code.
>I do not think it is in the F({Mod,Func}, As) call since
>a fun which F should be should show up as a valid code position
>in the Program counter.
>
>I hope that helps. Summary:
>
>You need at least the source code to understand anything. The assembly
>code gives more clarity. It is only values that need to survive the calls
>that are pushed (function arguments are passed in the 'x' VM register
>array). The return addresses belong to the stack frame below where they
>occur since they are first stored in CP and then pushed in the next
>stack frame.
>
>> 
>> 
>> Begin forwarded message:
>> Hi everyone,
>> erlang:process_display(Pid,backtrace) can display process's backtrace data. For example:
>> (foo@REDACTED)6> erlang:process_display(self(),backtrace).
>> Program counter: 0x00cf1498 (unknown function)
>> CP: 0x0245e8f8 (erl_eval:do_apply/6 + 208)
>> 
>> 
>> 0x03b1fb34 Return addr 0x01b7f060 (shell:exprs/7 + 368)
>> y(0)     []
>> y(1)     none
>> 
>> 
>> 0x03b1fb40 Return addr 0x01b7eb94 (shell:eval_exprs/7 + 80)
>> y(0)     []
>> y(1)     []
>> y(2)     cmd
>> y(3)     []
>> y(4)     {value,#Fun<shell.7.20862592>}
>> y(5)     {eval,#Fun<shell.24.20862592>}
>> y(6)     12305
>> y(7)     []
>> y(8)     []
>> y(9)     []
>> 
>> 
>> 0x03b1fb6c Return addr 0x01b7e968 (shell:eval_loop/3 + 308)
>> y(0)     []
>> y(1)     []
>> y(2)     []
>> y(3)     []
>> y(4)     <0.30.0>
>> y(5)     Catch 0x01b7ec08 (shell:eval_exprs/7 + 196)
>> 
>> 
>> 0x03b1fb88 Return addr 0x00a88f6c (<terminate process normally>)
>> y(0)     12305
>> y(1)     <0.30.0>
>> true
>> 
>> However, I don't know how to read the information above, such as what do "Program counter", Return addr", "+ 368" and "y(0) y(1) ..." mean? Can anyone teach me?
>> Thanks in advance!
>> 
>> 
>> 
>> 
>> 
>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>
>
>-- 
>
>/ Raimo Niskanen, Erlang/OTP, Ericsson AB
>_______________________________________________
>erlang-questions mailing list
>erlang-questions@REDACTED
>http://erlang.org/mailman/listinfo/erlang-questions
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20121118/49ec8592/attachment.htm>


More information about the erlang-questions mailing list