gdb 反汇编:以 16 为基数显示函数偏移量

Posted

技术标签:

【中文标题】gdb 反汇编:以 16 为基数显示函数偏移量【英文标题】:gdb disassemble: show function offsets in base 16 【发布时间】:2011-05-18 11:07:00 【问题描述】:

当反汇编函数时,gdb 将以 16 为基数显示内存地址,但以 10 为基数显示偏移量。

例子:

(gdb) disassemble unregister_sysctl_table
Dump of assembler code for function unregister_sysctl_table:
   0x00037080 <+0>: push   %ebp
   0x00037081 <+1>: mov    %esp,%ebp
   0x00037083 <+3>: sub    $0x14,%esp
   0x00037086 <+6>: mov    %ebx,-0xc(%ebp)
   0x00037089 <+9>: mov    %esi,-0x8(%ebp)
   0x0003708c <+12>:mov    %eax,%ebx
   0x0003708e <+14>:mov    %edi,-0x4(%ebp)

函数偏移量是地址旁边的&lt;+N&gt;,如您所见,它们的基数为 10。

当 Linux 内核崩溃时,它会显示使用 base 16 的回溯:

 [    0.524380]  [<c10381d5>] unregister_sysctl_table+0x65/0x70

必须将回溯地址从 base 16 转换为 base 10 才能找到所需的指令,这非常烦人。

可以告诉 gdb 以 16 为基数的偏移量显示反汇编输出吗?

【问题讨论】:

【参考方案1】:

GDB 当前使用硬编码的 '%d' 作为偏移量。

必须转换回溯地址非常烦人......才能找到所需的指令

你确实意识到你可以简单地做

x/i 0xc10381d5       # the crashing instruction (if looking at the inner frame)
x/i 0xc10381d5-5     # the call (if looking at caller frame)
x/10i 0xc10381d5-20  # context around the desired location

【讨论】:

【参考方案2】:

您必须修补 gdb 以显示十六进制偏移量。

例如,在 gdb 6.8 中,

在 cli-out.c、mi/mi-out.c、tui/tui-out.c 中更改 *_field_int

void
cli_field_int (struct ui_out *uiout, int fldno, int width,
enum ui_align alignment,
const char *fldname, int value)

char buffer[40]; /* FIXME: how many chars long a %d can become? */


cli_out_data *data = ui_out_data (uiout);
if (data->suppress_output)
    return;
sprintf (buffer, "%d:%X", value, value);
cli_field_string (uiout, fldno, width, alignment, fldname, buffer);

【讨论】:

以上是关于gdb 反汇编:以 16 为基数显示函数偏移量的主要内容,如果未能解决你的问题,请参考以下文章

[GDB]设置gdb反汇编语法为intel

Z80汇编:如何将带符号的8位值添加到16位寄存器?

GDB 问题 - 我如何逐行查看反汇编代码?

什么是反汇编?

GDB 反汇编使用不一致的寄存器命名

在 LLDB 中将反汇编风格设置为 Intel