Home | History | Annotate | Download | only in i386
History log of /src/sys/arch/i386/i386/db_machdep.c
RevisionDateAuthorComments
 1.10  24-Dec-2022  uwe {amd64,i386}/db_machdep.c: Don't bury a function call in an if condition

db_frame_info has many arguments and requires contorted line wrapping
that obscures the condition. The same object code is generated
(modulo a local variable moved closer to its only use site).
 1.9  24-Dec-2022  uwe {amd64,i386}/db_machdep.c: Use DB_SYM_NULL
 1.8  13-Dec-2021  chs ddb: fix function names of "noreturn" functions in stack traces.

when looking up function names for stack traces (where the addresses are the
return addresses of function calls), if the address is the first instruction
in the function, assume that the function being called is marked "noreturn"
and that the function containing the call is actually the function immediately
before the address that we looked up. to find the correct function name,
do the lookup again with (address - 1) and then add one to the offset within
the function that we find.
 1.7  11-Feb-2018  maxv Style, and reduce the diff between i386 and amd64. No functional change.
 1.6  15-Aug-2017  maxv Remove __ELF__ vestige.
 1.5  11-Jan-2014  christos branches: 1.5.6;
stop ddb backtrace at Xsoftintr() (Richard Hansen)

Stop unwinding frames when db_stack_trace_print() encouters
Xsoftintr(). This avoids a recursive panic() due to an invalid
pointer dereference when a software interrupt panic()s.

Here's what happens without this change:

When db_stack_trace_print() runs during a panic() and db_nextframe()
encounters the Xsoftintr() frame, db_nextframe() does the following at
db_machdep.c:292:

1. checks to see if there's a Xsoftintr() symbol (there is)
2. checks to see if the frame corresponds to an interrupt (the
symbol name begins with "Xsoft" so it does)

If both of the above are true (they are), db_nextframe() at
db_machdep.c:303 tries to get a pointer to a struct intrframe.
According to the comment at line 300, the second argument passed to
Xsoftintr() is a pointer to a struct intrframe. However, the comment
and the corresponding code are not correct -- Xsoftintr() doesn't take
any arguments[1]. Attempting to fetch the second argument only yields
stack garbage, not a struct intrframe. This causes db_machdep.c:307
to dereference a bad pointer, triggering the recursive panic().

[1] Xsoftintr() is called by Xspllower() which is called by splx()
a.k.a. spllower(). Neither Xspllower() nor Xsoftintr() set up a
standard frame when called (they don't do 'pushl %ebp; movl %esp,
%ebp'), so Xsoftintr()'s %ebp is the same as splx()'s %ebp. This
makes splx()'s arguments look like Xsoftintr()'s arguments, and
splx() does not take any arguments.

You can reproduce the recursive panic by reverting this change and
adding a call to panic() inside ipintr(). The backtrace will look
like the following (the line numbers you see might differ from these
line numbers -- this backtrace was generated from a slightly modified
version of the NetBSD 6.1 kernel):

#0 vpanic (fmt=0xc0ba995b "trap", ap=0xdaa51730) at /usr/src/sys/kern/subr_prf.c:211
#1 0xc0790529 in panic (fmt=0xc0ba995b "trap") at /usr/src/sys/kern/subr_prf.c:205
#2 0xc07decbc in trap (frame=0xdaa517c0) at /usr/src/sys/arch/i386/i386/trap.c:396
#3 0xc010cf48 in ?? () at /usr/src/sys/arch/i386/i386/vector.S:983
#4 0xc02857f0 in db_get_value (addr=56, size=4, is_signed=false) at /usr/src/sys/ddb/db_access.c:72
#5 0xc028a09a in db_nextframe (nextframe=0xdaa51b40, retaddr=0xdaa51b3c, arg0=0xdaa51b38, ip=0xdaa51b34, argp=0xdaa51d88, is_trap=0, pr=0xc07901b5 <printf>) at /usr/src/sys/arch/i386/i386/db_machdep.c:308
#6 0xc028be2b in db_stack_trace_print (addr=<optimized out>, have_addr=true, count=65533, modif=0xc0bb44bf "", pr=0xc07901b5 <printf>) at /usr/src/sys/arch/x86/x86/db_trace.c:275
#7 0xc07903cb in vpanic (fmt=0xc0b6ba76 "testing", ap=0xdaa51d4c) at /usr/src/sys/kern/subr_prf.c:296
#8 0xc0790529 in panic (fmt=0xc0b6ba76 "testing") at /usr/src/sys/kern/subr_prf.c:205
#9 0xc04e3d4f in ipintr () at /usr/src/sys/netinet/ip_input.c:369
#10 0xc054ac0d in softint_execute (s=<optimized out>, si=<optimized out>, l=<optimized out>) at /usr/src/sys/kern/kern_softint.c:543
#11 softint_dispatch (pinned=0xc4085560, s=4) at /usr/src/sys/kern/kern_softint.c:825
#12 0xc0100fdb in ?? () at /usr/src/sys/arch/i386/i386/spl.S:390
#13 0xc07d2e11 in tcp_usrreq (so=0xc40b0534, req=4, m=0x0, nam=0xc317ba00, control=0x0, l=0xc4085560) at /usr/src/sys/netinet/tcp_usrreq.c:615
#14 0xc04bb300 in tcp_usrreq_wrapper (a=0xc40b0534, b=4, c=0x0, d=0xc317ba00, e=0x0, f=0xc4085560) at /usr/src/sys/netinet/in_proto.c:164
#15 0xc0839006 in soconnect (so=0xc40b0534, nam=0xc317ba00, l=0xc4085560) at /usr/src/sys/kern/uipc_socket.c:821
#16 0xc083c4ce in do_sys_connect (l=0xc4085560, fd=4, nam=0xc317ba00) at /usr/src/sys/kern/uipc_syscalls.c:371
#17 0xc083dbeb in sys_connect (l=0xc4085560, uap=0xdbc27d00, retval=0xdbc27d28) at /usr/src/sys/kern/uipc_syscalls.c:350
#18 0xc07b1b4a in sy_call (rval=0xdbc27d28, uap=0xdbc27d00, l=0xc4085560, sy=0xc0c2f018) at /usr/src/sys/sys/syscallvar.h:61
#19 syscall (frame=0xdbc27d48) at /usr/src/sys/arch/x86/x86/syscall.c:179
#20 0xc010056d in ?? () at /usr/src/sys/arch/i386/i386/locore.S:1160
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
 1.4  12-Jul-2012  dsl branches: 1.4.2; 1.4.4;
Neither i386 nor amd64 have had separate syscall_plain/fancy functions
for ages, so this code can't be correct in looking for them.
Change to compare against "syscall".
I don't know if this changes any behaviour anywhere.
 1.3  14-Apr-2011  yamt branches: 1.3.2; 1.3.4; 1.3.8; 1.3.10; 1.3.16;
fix backtrace of interrupt
 1.2  11-Apr-2011  mrg obsolete DB_AOUT_SYMBOLS. however, we need to leave most of the code
in db_sym.[ch] as it is used by the elf version of crash(8).

i will be cleaning up the db_sym.c code in a follow up commit to avoid
having dead code compiled.
 1.1  10-Apr-2011  christos Merge db_trace for x86. From: Vladimir Kirillov proger at wilab dot org dot ua
 1.3.16.1  07-Feb-2014  sborrill Pull up the following revisions(s) (requested by christos in ticket #1017):
sys/arch/x86/include/db_machdep.h: revision 1.4
sys/arch/i386/i386/db_machdep.c: revision 1.5

Fix ddb backtrace for softintr (i386).
 1.3.10.2  22-May-2014  yamt sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs. ("Protocol error: too many arguments")
 1.3.10.1  30-Oct-2012  yamt sync with head
 1.3.8.2  06-Jun-2011  jruoho Sync with HEAD.
 1.3.8.1  14-Apr-2011  jruoho file db_machdep.c was added on branch jruoho-x86intr on 2011-06-06 09:05:48 +0000
 1.3.4.2  02-May-2011  jym Sync with head.
 1.3.4.1  14-Apr-2011  jym file db_machdep.c was added on branch jym-xensuspend on 2011-05-02 22:49:55 +0000
 1.3.2.2  21-Apr-2011  rmind sync with head
 1.3.2.1  14-Apr-2011  rmind file db_machdep.c was added on branch rmind-uvmplock on 2011-04-21 01:41:06 +0000
 1.4.4.1  18-May-2014  rmind sync with head
 1.4.2.2  03-Dec-2017  jdolecek update from HEAD
 1.4.2.1  20-Aug-2014  tls Rebase to HEAD as of a few days ago.
 1.5.6.1  28-Aug-2017  skrll Sync with HEAD

RSS XML Feed