max at bruningsystems.com ??: > Hi Brian, > > Brian Xu - Sun Microsystems - Beijing China wrote: > >> Hi, >> >> I have a question: how the cmd '::findstack -v' in mdb works? >> >> Likewise in sparc, since at any time only the current register window >> can be accessed, so if we want to backtrace the stack, we can only >> access the fp(i6) and args(i0-i5) of the function's father, and how we >> can access those of the grandfather, great grandfather, etc? >> >> >> > > |SPARC uses register windows for most argument passing. Basically, > if a function executes the "save" instruction at or near the beginning > and the "restore" instruction at the end, there is a save area for registers > on the stack. When a thread switch occurs, or a window spill trap > occurs (a save executed, but no more windows), the register window(s) > that need to be saved are placed in the save area on the stack. > If a function does not use save/restore, arguments are in the output > registers. There are six registers used for argument passing. If a > function takes more than 6 arguments, the additional arguments are placed > in the caller's frame at a fixed location from the top. > Thanks for the info.
I have a question about the meaning of 'when a thread switch occurs'. Here the thread means which thread, the current thread? If there is no window spill, and we set a breakpoint in a thread, when the thread stops at the breakpoint, since the thread switch occurs, then $c will list the values of the args of each function on the stack, right? (we also consider the STOP as a thread state transition) Another question is(it also my original question), even the trap handler can only access the current register window, how it can put the registers of other window in the save area? Here I think it is the trap handler or the swtch that put the value of registers in the save area. I think the handler execute the 'flushw' instruction or repeat execute the 'restore' instruction. right? > The following shows an example. Note that for 64-bit SPARC, the > stack pointer (%sp) and the frame pointer (%fp) are adjusted by 0x7ff > (the ABI-Bias). The bias is there for two reasons. First, it allows > trap handling code to quickly determine if it needs to save 32-bit > or 64-bit values (with the bias, 64-bit stack pointer is always an odd > number (lowest bit set)). Second, it allows more space to be > accessed using "immediate" addressing (for example, "ld [%fp+offset], %l0"). > "offset" is an immediate value and is a signed, 13-bit value. By using the > abi-bias, the range of stack addresses that can be accessed with immediate > addressing is increased. Let me know if you want more information on this. > then the 'save' function at the beginning of a function should be, save %sp, xx, %sp where xx=0x7ff + 24(the size of the register window) + 'extra area for local variables' for 64bit and xx=24 + 'extra area for local variables' for 32bit, right? > # *mdb -k* > > *::threadlist* *-v* /<-- stack backtrace for all kernel threads/ > /< output truncated >/ > ============== thread_id 30000aa5500 > 0x30000b2ced9: > process args /usr/sbin/inetd -s /<-- inetd / > 0x30000aa5610: lwp procp wchan > 30000b4dba0 30000b2ca48 300007fe87a > 0x30000aa5538: > pc sp > cv_wait_sig_swap+0x184 2a1003650a1 <-- stack pointer is odd > (i.e., has ABI-bias)// > cv_waituntil_sig+0x14(300007fe87a, 300007fe840, 0, 0, 3b, 20) > poll+0x424(ffbff5f8, 30000998d08, 3000004ec48, ffffffffffffffff, 0, 188) > syscall_trap32+0xa8(ffbff5f8, 31, ffffffffffffffff, 0, 1c, 40) > > /< output truncated >/ > > *2a1003650a1$c* /<-- 2a1003650a1 is sp of inetd/ > cv_waituntil_sig+0x14(300007fe87a, 300007fe840, 0, 0, 3b, 20) > poll+0x424(ffbff5f8, 30000998d08, 3000004ec48, ffffffffffffffff, 0, 188) > syscall_trap32+0xa8(ffbff5f8, 31, ffffffffffffffff, 0, 1c, 40) > > *2a1003650a1$C* /<-- upper-case $C gives frame pointer at each frame/ > 000002a100365151 cv_waituntil_sig+0x14(300007fe87a, 300007fe840, 0, 0, 3b, 20) > 000002a100365211 poll+0x424(ffbff5f8, 30000998d08, 3000004ec48, > ffffffffffffffff > , 0, 188) > 000002a1003652f1 syscall_trap32+0xa8(ffbff5f8, 31, ffffffffffffffff, 0, 1c, > 40) > > *30000aa5500::print kthread_t t_pcb* /<-- get the pc and sp from the thread > of inetd/ > { > t_pcb.val = [ 0x107bd1c, 0x2a1003650a1 ] > } > > *107bd1c/ai* /<-- same pc as threadlist shows/ > cv_wait_sig_swap+0x184: > cv_wait_sig_swap+0x184: call -0x3aeb4 > > | > > The following shows the register save areas for each stack frame for > |inetd|. > > | > > *2a1003650a1+7ff,10/K* /<-- must add V9 bias, display 16 64-bit hex > values/ > 0x2a1003658a0: 30000b4dba0 30000b2ca48 0 300007fe87a > /<-- %l0-%l3/ > 938 0 30000aa5500 fffd > /<-- %l4-%l7/ > 0 300007fe840 20 3000004edce > /<-- %i0-%i3/ > 2a100365a00 0 2a100365151 107c14c > /<-- %i4-%i7/ > > *107c14c/ai* /<-- %i7 is saved program counter/ > cv_waituntil_sig+0x14: > cv_waituntil_sig+0x14: call -0x5b4 > > *2a100365151+7ff,10/K* /<-- %i6 is saved frame pointer, use to get previous > frame/ > 0x2a100365950: 0 3000004ec48 3b 0 > 30000c05798 30 300007fe840 30000bbb600 > 300007fe87a 300007fe840 0 0 > 3b 20 2a100365211 10bb378 > > *10bb378/ai* /<-- and repeat.../ > poll+0x424: > poll+0x424: call -0x3f240 > > *2a100365211+7ff,10/K* > 0x2a100365a10: 30000998d48 300007fe840 0 31 > 30000998d58 0 0 0 > ffbff5f8 30000998d08 3000004ec48 > ffffffffffffffff 0 188 > 2a1003652f1 10343fc > > *10343fc/ai* /<-- and again.../ > syscall_trap32+0xa8: > syscall_trap32+0xa8: jmpl %g3, %o7 > > *2a1003652f1+7ff,10/K* > 0x2a100365af0: 1007254 2a100365ba0 30000b4dba0 1034354 > 1448000 0 30000aa5500 2a100365ba0 > ffbff5f8 31 ffffffffffffffff > 0 1c 40 ffbff598 > ff14d474 > > *ff14d474/ai* /<-- and again, but here kernel is returning to user address/ > 0xff14d474: > mdb: failed to read instruction at ff14d474: no mapping for address > 0xff14d474: > > In the above output, each frame's window save area is displayed. > Hope this helps. For 32-bit programs, the technique is the same, only you > don't > add 7ff, since the ABI-bias is not used. > > Basically, ::findstack does the same walk that I am doing by hand in > the above output. > very detailed info, impressive! Thanks, Brian > max > > > | > > >> Thanks, >> Brian >> >> _______________________________________________ >> mdb-discuss mailing list >> mdb-discuss at opensolaris.org >> >> >> > > _______________________________________________ > mdb-discuss mailing list > mdb-discuss at opensolaris.org >