Stack traces: Difference between revisions

Line 1,371:
in sub f at bt:2
in sub MAIN at bt:3</pre>
 
=={{header|Phix}}==
There no standard method of obtaining a stack trace mid-run (as yet, non-fatally that is), but we can quickly cobble something together:
<lang Phix>constant W = machine_word(),
{RTN,PREVEBP} = iff(W=4?{8,20}:{16,40})
 
procedure show_stack()
sequence symtab, symtabN
integer rtn
atom prev_ebp
 
#ilASM{
[32]
lea edi,[symtab]
call :%opGetST -- [edi]=symtab (ie our local:=the real symtab)
mov edi,[ebp+20] -- prev_ebp
mov eax,[edi+8] -- calling routine no
mov [rtn],eax
mov eax,edi
lea edi,[prev_ebp]
call :%pStoreMint
[64]
lea rdi,[symtab]
call :%opGetST -- [rdi]=symtab (ie our local:=the real symtab)
mov rdi,[rbp+40] -- prev_ebp
mov rax,[rdi+16] -- calling routine no
mov [rtn],rax
mov rax,rdi
lea rdi,[prev_ebp]
call :%pStoreMint
[]
}
while 1 do
symtabN = symtab[rtn]
?symtabN[1]
prev_ebp = peekNS(prev_ebp+PREVEBP,W,0)
rtn = peekNS(prev_ebp+RTN,W,0)
if rtn=21 then exit end if -- (T_maintls, main top level routine, always present)
end while
end procedure
 
procedure three(bool die)
if die then
?9/0
else
show_stack()
end if
end procedure
 
procedure two(bool die)
three(die)
end procedure
 
procedure one(bool die)
two(die)
end procedure
 
one(0)
?routine_id("dummy") -- see note below
one(1)</lang>
During compilation, the symbol table entries hold an integer ternary tree index rather than a string name, and normally
things are left like that during interpretation (the proper string names are always written out when an executable is
created) unless and until a fatal error occurs, or the compiler has evidence that they might be needed, such as that
unresolved routine_id("dummy"). The -1 in the output below is that call failing to find any such routine.
{{Out}}
<pre>
"three"
"two"
"one"
-1
 
C:\Program Files (x86)\Phix\e01.exw:59 in procedure three()
attempt to divide by 0
die = 1
... called from C:\Program Files (x86)\Phix\e01.exw:66 in procedure two()
die = 1
... called from C:\Program Files (x86)\Phix\e01.exw:70 in procedure one()
die = 1
... called from C:\Program Files (x86)\Phix\e01.exw:75
 
Global & Local Variables
 
--> see C:\Program Files (x86)\Phix\ex.err
Press Enter...
</pre>
The first half (up to the -1) is the output from show_stack_trace(), the rest is standard fatal error diagnostics.<br>
For more details of how the latter is actually produced, refer to builtins\VM\pDiagN.e - in particular the conversion of
raw addresses into source code line numbers is not trivial (and not worth trying to replicate here). In fact I didn't just
type all that #ilASM gunk above in, but instead copied it from other source files in builtins\VM.
 
Alternatively, but only when interpreting (whereas the above works as shown both when interpreting and pre-compiled), the debugger is
started with the much saner
<lang Phix>trace(1)</lang>
though as yet it offers no means of examining the stack trace (resume-ably), the above suggests it should be relative easy to add.
 
=={{header|PHP}}==
7,795

edits