Остановка на точке останова в функции переменных аргументов - PullRequest
1 голос
/ 31 января 2012

У меня есть следующая функция, и я хочу остановить для отладки внутри нее в зависимости от содержимого переменных аргументов, переданных ей.

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.
  • Я знаю, как установить условные контрольные точки, я хочу знать, что условие должно быть в этом случае.

Ответы [ 3 ]

2 голосов
/ 31 января 2012

Я думаю, что вопрос / ответ состоит из двух частей:

  1. Как получить GDB для просмотра параметров, передаваемых в переменной части?Я не думаю, что он обладает такой способностью, поэтому вам придется делать что-то зависящее от платформы. Этот ответ должен работать для x86_64.Для 32-битных это более просто, потому что va_list это просто массив длинных.
  2. Как сделать условную точку останова?Команда gdb condition (задокументированная здесь ) может помочь.
1 голос
/ 31 января 2012

GDB может сделать это. Вам просто нужна переменная (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 в условие разрыва.

0 голосов
/ 31 января 2012

Вам придется проанализировать кишки типа вашей реализации va_list.Например, это может быть указатель на массив указателей, один из которых (вероятно, первый) указывает на «привет».Затем научите ваш отладчик нарушать это условие.

...