【问题标题】:Stopping on breakpoint in a variable arguments function在可变参数函数中的断点处停止
【发布时间】:2012-02-23 06:37:38
【问题描述】:

我有一个以下函数,我想根据传递给它的变量参数的内容停止在其中进行调试。

int
my_fprintf (const char *format, ...)
{
  va_list arg_list;
  ...
  va_start (arg_list, format);
  result = vfprintf (stream, indent_str, arg_list);
  va_end (arg_list);

  ...
  return result;
}

例如,如果调用是my_fprintf ("%s", "hello"),我想要在其中放置一个断点以停止(因此断点条件将尽可能接近<smth> == "hello")。

有可能吗?

更新:

  • 调试器是 gdb。
  • 我知道如何设置条件断点,我想知道,条件应该是这种情况。

【问题讨论】:

  • 您可能会发现准确说明您正在使用的调试器是相关的。

标签: c debugging list arguments


【解决方案1】:

我认为问题/答案分为两部分:

  1. 如何让gdb看到变量部分传入的参数?我不认为它有这种能力,所以你必须做一些平台相关的事情。 This answer 应该适用于 x86_64。对于 32 位,它更简单,因为 va_list 只是一个 long 数组。
  2. 如何设置条件断点? gdb 的condition 命令(记录在here)可以提供帮助。

【讨论】:

  • 是的,它似乎一般都可以工作,唯一悬而未决的问题是断点条件下的字符串比较
【解决方案2】:

gdb 可以做到这一点。您只需要一个可以检查的变量(以下 sn-p 中的p)。要成功获得p,您需要更多的goo,即检查arg2 的第一个参数是否为char*,例如检查format 是否包含%s(尽管%s 不够,因为有人可能会使用 %.*s 或其他东西)。

static int my_fprintf(const char *format, ...)
{
        const char *p;
        va_list arg_list, arg2;
        bool have_string = false;

        va_start(arg_list, format);
        va_copy(arg2, arg_list);
        for (p = strchr(format, '%'); p != NULL; p = strchr(p+1, '%')) {
                if (p[1] == '%')
                        continue;
                if (p[1] != 's')
                        break;
                have_string = true;
                break;
        }
        if (have_string)
                p = va_arg(arg2, const char *);
        result = vfprintf(stream, indent_str, arg_list);
        va_end(arg_list);
        return result;
}

(gdb) b 1234 if have_string && strstr(p, "hello")==0

将 1234 替换为 p=va_arg... 的行号。
编辑:取消阴影 p 并将 have_string 放入 break cond。

【讨论】:

  • 你正在隐藏在函数顶部声明的 p)
  • 在我看来,if (have_string) ... 应该有一个 else { p = "" } 来处理没有字符串的情况。然后我使用strcmp 进行严格的字符串比较。除此之外,就像一个魅力!谢谢。
【解决方案3】:

您必须分析实现的 va_list 类型的内容。例如。它可能是指向指针数组的指针,其中一个(可能是第一个)指向“你好”。然后教你的调试器在这种情况下中断。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    • 1970-01-01
    • 2015-09-11
    • 2016-05-28
    相关资源
    最近更新 更多