【问题标题】:How to debug whether a pointer argument was modified by a function?如何调试指针参数是否被函数修改?
【发布时间】:2018-02-22 20:52:05
【问题描述】:

我目前正在尝试分析一个大型复杂函数的行为,该函数需要大量指针输入。考虑以下签名。

int myfunc(typeA *paramA, typeB *paramB);

被调用为

myfunc(argA, argB);

如果argAargB 的指针位置被写入,是否可以使用调试器进行观察?还是只能观察内存位置是否发生变化(在我的情况下绝对不会发生)?

我想检查函数调用前后这些指针参数的差异。这款手表可以吗?

请注意,传递的这些类/结构非常庞大,还有其他指向类/结构的指针。所以,一个一个地观察每个变量将是我最后的手段

【问题讨论】:

  • gcc/clang 有观察点,vc 有数据断点。
  • @Jarod42 是的,我知道观察点。我在问是否可以查看任何类/结构成员是否已更改。

标签: c++ debugging lldb clion


【解决方案1】:

由于您使用 CLion 标记了您的帖子,我认为这就是您正在使用的 IDE。您可能想阅读这篇文章: https://blog.jetbrains.com/clion/2015/05/debug-clion/

特别是手表部分:

在每个点捕获每个变量会导致信息过多。有时,您希望关注特定变量以及它在整个程序执行过程中的变化方式,包括在所讨论的变量不是您正在检查的代码的本地变量时监控变化。这就是 Debug 工具窗口的 Watch 区域的用途。

要开始观察变量,只需按添加按钮 (Alt+Insert (Windows/Linux)/⌘N (OS X)) 并输入要观察的变量的名称。此处也提供代码补全。

根据您的评论: 您可以选择查看何时写入内存:Can I set a breakpoint on 'memory access' in GDB?

否则如果你只是想知道值是否被更改以进行调试,只需在调用函数之前复制该值即可:

typeA copyOfA = *argA;
myfunc(&copyOfA, argB);

if (copyOfA != *argA)
{
    // It's changed
}

【讨论】:

  • 嗯,我已经知道那部分了。我需要知道类/结构的任何成员是否已更改。
【解决方案2】:

不确定我是否准确地得到了你的问题,我不知道 clion 是否允许你访问 lldb 脚本解释器,但是给出这个例子:

struct Foo
{
  int a;
  int b;
  int c;
};

void ChangeFoo(struct Foo *input)
{
  input->a += 10;
}

int
main()
{
  struct Foo my_foo = {10, 20, 30};
  ChangeFoo(&my_foo);
  return 0;
}

从命令行 lldb 你可以这样做:

(lldb) br s -l 17
Breakpoint 1: where = tryme`main + 39 at tryme.c:17, address = 0x0000000100000f97
(lldb) br s -l 18
Breakpoint 2: where = tryme`main + 46 at tryme.c:18, address = 0x0000000100000f9e
(lldb) run
Process 16017 launched: '/tmp/tryme' (x86_64)
Process 16017 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100000f97 tryme`main at tryme.c:17
   14   main()
   15   {
   16     struct Foo my_foo = {10, 20, 30};
-> 17     ChangeFoo(&my_foo);
          ^
   18     return 0;
   19   }
Target 0: (tryme) stopped.
(lldb) script value = lldb.frame.FindVariable("my_foo")
(lldb) script print value
(Foo) my_foo = {
  a = 10
  b = 20
  c = 30
}
(lldb) n
Process 16017 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
    frame #0: 0x0000000100000f9e tryme`main at tryme.c:18
   15   {
   16     struct Foo my_foo = {10, 20, 30};
   17     ChangeFoo(&my_foo);
-> 18     return 0;
          ^
   19   }
Target 0: (tryme) stopped.
(lldb) script
Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
>>> for i in range(0,value.GetNumChildren()):
...     print(i, " ", value.GetChildAtIndex(i).GetValueDidChange())
... 
(0, ' ', True)
(1, ' ', False)
(2, ' ', False)
>>> print value.GetChildAtIndex(0)
(int) a = 20

注意,如果上面的my_foo 是一个指针,我们只会获取不是您想要比较的指针值。在这种情况下,当您捕获该值时,请执行以下操作:

(lldb) 脚本值 = lldb.frame.FindVariable("my_foo_ptr").Dereference()

你最初获得价值的地方,然后一切都将如上所示。

【讨论】:

    猜你喜欢
    • 2017-07-27
    • 2016-12-18
    • 2012-11-27
    • 2021-06-05
    • 1970-01-01
    • 2021-02-02
    • 1970-01-01
    • 2012-05-28
    相关资源
    最近更新 更多