]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: debug: in call traces, dump the 8 bytes before the return address, not after
authorWilly Tarreau <w@1wt.eu>
Mon, 14 Apr 2025 17:28:22 +0000 (19:28 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 14 Apr 2025 17:28:22 +0000 (19:28 +0200)
In call traces, we're interested in seeing the code that was executed, not
the code that was not yet. The return address is where the CPU will return
to, so we want to see the bytes that precede this location. In the example
below on x86 we can clearly see a number of direct "call" instructions
(0xe8 + 4 bytes). There are also indirect calls (0xffd0) that cannot be
exploited but it gives insights about where the code branched, which will
not always be the function above it if that one used tail branching for
example. Here's an example dump output:

         call ------------,
                          v
       0x6bd634 <64 8b 38 e8 ac f7 ff ff]: debug_handler+0x84/0x95
 0x7fa4ea2593a0 <00 00 00 00 0f 1f 40 00]: libpthread:+0x123a0
       0x752132 <00 00 00 00 00 90 41 55]: htx_remove_blk+0x2/0x354
       0x5b1a2c <4c 89 ef e8 04 07 1a 00]: main+0x10471c
       0x5b5f05 <48 89 df e8 8b b8 ff ff]: main+0x108bf5
       0x60b6f4 <89 ee 4c 89 e7 41 ff d0]: tcpcheck_eval_send+0x3b4/0x14b2
       0x610ded <00 00 00 e8 53 a5 ff ff]: tcpcheck_main+0x7dd/0xd36
       0x6c5ab4 <48 89 df e8 5c ab f4 ff]: wake_srv_chk+0xc4/0x3d7
       0x6c5ddc <48 89 f7 e8 14 fc ff ff]: srv_chk_io_cb+0xc/0x13

src/debug.c

index ebf79cb7b102aba74893434b84468f6bf930c1b0..b0effdd4b749c35bf5423e83d7027a80ecbddcef 100644 (file)
@@ -207,7 +207,7 @@ void ha_dump_backtrace(struct buffer *buf, const char *prefix, int dump)
                        j = 0;
                }
                bak = *buf;
-               dump_addr_and_bytes(buf, pfx2, callers[j], 8);
+               dump_addr_and_bytes(buf, pfx2, callers[j], -8);
                addr = resolve_sym_name(buf, ": ", callers[j]);
                if ((dump & 3) == 0) {
                        /* dump not started, will start *after* ha_thread_dump_one(),