From: Willy Tarreau Date: Mon, 14 Apr 2025 17:25:27 +0000 (+0200) Subject: MINOR: tools: let dump_addr_and_bytes() support dumping before the offset X-Git-Tag: v3.2-dev11~66 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=003f5168e47f6755990b8315757ecd71ef684c56;p=thirdparty%2Fhaproxy.git MINOR: tools: let dump_addr_and_bytes() support dumping before the offset 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 --- diff --git a/src/tools.c b/src/tools.c index 86135f6a8..2e4858854 100644 --- a/src/tools.c +++ b/src/tools.c @@ -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 will be considered empty. + * if 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))