]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tools: let dump_addr_and_bytes() support dumping before the offset
authorWilly Tarreau <w@1wt.eu>
Mon, 14 Apr 2025 17:25:27 +0000 (19:25 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 14 Apr 2025 17:25:27 +0000 (19:25 +0200)
For code dumps, dumping from the return address is pointless, what is
interesting is to dump before the return address to read the machine
code that was executed before branching. Let's just make the function
support negative sizes to indicate that we're dumping this number of
bytes to the address instead of this number from the address. In this
case, in order to distinguish them, we're using a '<' instead of '[' to
start the series of bytes, indicating where the bytes expand and where
they stop. For example we can now see this:

       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/tools.c

index 86135f6a81f2e41105ba5e1733035fdd500ef812..2e4858854810b42d3e9ec5875c1dce1d9d44d7ad 100644 (file)
@@ -5184,13 +5184,23 @@ void dump_hex(struct buffer *out, const char *pfx, const void *buf, int len, int
  *    "0x7f10b6557690 [48 c7 c0 0f 00 00 00 0f]"
  * It relies on may_access() to know if the bytes are dumpable, otherwise "--"
  * is emitted. A NULL <pfx> will be considered empty.
+ * if <n> is negative, then the bytes before the address are dumped instead, so
+ * that the address ends after the last byte. This can be handy for call traces
+ * where the code that follows hasn't been executed but the code that precedes
+ * usually contains a call instruction. In this case, the opening bracket uses
+ * a '<' instead of '[' to indicate that the address is at the ']'.
  */
 void dump_addr_and_bytes(struct buffer *buf, const char *pfx, const void *addr, int n)
 {
        int ok = 0;
        int i;
 
-       chunk_appendf(buf, "%s%#14lx [", pfx ? pfx : "", (long)addr);
+       chunk_appendf(buf, "%s%#14lx %c", pfx ? pfx : "", (long)addr, (n < 0) ? '<' : '[');
+
+       if (n < 0) {
+               addr += n;
+               n = -n;
+       }
 
        for (i = 0; i < n; i++) {
                if (i == 0 || (((long)(addr + i) ^ (long)(addr)) & 4096))