【问题标题】:How to print the memory address and the value of the arguments of a C/C++ function that is being debugged with LLDB?如何打印正在使用 LLDB 调试的 C/C++ 函数的内存地址和参数值?
【发布时间】:2015-11-05 11:36:07
【问题描述】:

我正在为我的操作系统测试做准备。我们使用的工具之一是调试器 (LLDB),我的目标是检查 C 函数或 C++ 方法的参数。

例如:我如何查看内存地址和传递给 _SMenuItemCommandID 的参数值? - 我尝试过不同的东西,但在尝试中死了。

HITestBox`_SMenuItemCommandID(MenuData*, unsigned short, unsigned long):
0x9a7bfc35:  pushl  %ebp
0x9a7bfc36:  movl   %esp, %ebp
0x9a7bfc38:  pushl  %esi
0x9a7bfc39:  subl   $52, %esp
0x9a7bfc3c:  movl   8(%ebp), %esi
0x9a7bfc3f:  movl   88(%esi), %eax
0x9a7bfc42:  movl   %eax, -16(%ebp)
0x9a7bfc45:  movzwl 12(%ebp), %ecx
0x9a7bfc49:  movw   %cx, -12(%ebp)
0x9a7bfc4d:  movl   $0, -8(%ebp)
0x9a7bfc54:  leal   -8(%ebp), %edx
0x9a7bfc57:  movl   %edx, 28(%esp)
0x9a7bfc5b:  movl   %ecx, 4(%esp)
0x9a7bfc5f:  movl   %eax, (%esp)
0x9a7bfc62:  movl   $0, 24(%esp)
0x9a7bfc6a:  movl   $4, 20(%esp)
0x9a7bfc72:  movl   $0, 16(%esp)
0x9a7bfc7a:  movl   $1835232612, 12(%esp)
0x9a7bfc82:  movl   $12, 8(%esp)
0x9a7bfc8a:  calll  0x9a5f7c9b                ; elementGetDataAtIndex
0x9a7bfc8f:  movl   16(%ebp), %eax
0x9a7bfc92:  cmpl   %eax, -8(%ebp)
0x9a7bfc95:  je     0x9a7bfcae                ; _SMenuItemCommandID(MenuData*, unsigned short, unsigned long) + 121
0x9a7bfc97:  movl   %eax, 4(%esp)
0x9a7bfc9b:  leal   -16(%ebp), %eax
0x9a7bfc9e:  movl   %eax, (%esp)
0x9a7bfca1:  calll  0x9a7e2914                ; mID::SetCommandID(unsigned long)
0x9a7bfca6:  movl   %esi, (%esp)
0x9a7bfca9:  calll  0x9a5f7c65                ; invalidate(MenuData*)
0x9a7bfcae:  xorl   %eax, %eax
0x9a7bfcb0:  addl   $52, %esp
0x9a7bfcb3:  popl   %esi
0x9a7bfcb4:  popl   %ebp
0x9a7bfcb5:  ret    

编辑: 假设我正在调试一个没有源代码的应用程序,但我导出了符号。 比如说,在某个时刻,这段代码会被执行:

MenuData *myData = (MenuData *)0x28ff44;;
SMenuItemCommandID(myData, 3, 4);

我需要做什么(使用 LLDB)才能获得:

arg0 = 0x28ff44   
arg1 =3  
arg2 =4  

【问题讨论】:

  • 你是从 XCode 还是从命令行使用 lldb?
  • 您应该能够在函数上设置断点并逐步执行 - 它会向您显示所有内容。
  • 如果我有被检查的应用程序的代码,那就可以了。但是,如果我正在调试一个我没有源代码的应用程序怎么办? (例如,这是我们老师的一个测试应用,它导出了符号)。
  • 它的工作方式相同...在终端中(例如lldb some.app),然后在函数或偏移量上设置断点。
  • 对。我看到 3 组(异常状态寄存器、浮点寄存器、通用寄存器)。但是,仍然不知道如何获取参数值。 (我更新了我的问题以反映我真正想要的)。谢谢!

标签: c++ c xcode debugging lldb


【解决方案1】:

您发布的反汇编是x86。参数在堆栈上。如果在函数 prolog 之前中断,则参数相对于堆栈指针 %esp(在 lldb 中作为 $esp 访问):

# The return address:
x/w $esp
# The first argument:
x/w $esp+4
# The second argument:
x/w $esp+8

如果您在序言(在您的示例中为0x9a7bfc3c)之后中断,通常会在此处放置符号断点,则会找到相对于帧指针(%ebp 又名$ebp)的参数:

# The saved frame pointer of the previous frame:
x/w $ebp
# The return address:
x/w $ebp+4
# The first argument:
x/w $ebp+8
# The second argument:
x/w $ebp+12

对于其他架构,参数的存储方式不同,通常存储在寄存器中。此外,上面假设了“cdecl”调用约定。还有其他的。您是否被告知需要熟悉哪些架构和调用约定?

【讨论】:

  • 架构:32位,调用约定:x86
猜你喜欢
  • 2013-11-13
  • 1970-01-01
  • 2012-08-13
  • 2015-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-22
  • 1970-01-01
相关资源
最近更新 更多