Как отладить аномальные проблемы памяти / стека C - PullRequest
0 голосов
/ 17 мая 2010

Извините, я не могу быть конкретным с кодом, но проблемы, которые я вижу, являются аномальными. Значения символьных строк, похоже, меняются в зависимости от другого, не связанного с ним кода. Например, значение аргумента, который передается ниже, будет меняться просто в зависимости от того, закомментирую ли я один или два вызова fprintf ()! В последнем fprintf () значение обычно полностью пустое (и нет, я проверил, чтобы убедиться, что я не изменяю аргумент напрямую ... все, что мне нужно сделать, это закомментировать fprintf () или добавить другой fprintf () и значение строки изменится в определенных точках!):

static process_args(char *arg) {
    /* debug */
    fprintf(stderr, "Function arg is %s\n", arg);

    ...do a bunch of stuff including call another function that uses alloc()...

    /* debug */
    fprintf(stderr, "Function arg is now %s\n", arg);    
}

int main(int argc, char *argv[]) {
    char *my_arg;

    ... do a bunch of stuff ...

    /* just to show you it's nothing to do with the argv array */
    my_string = strdup(argv[1]);

    /* debug */
    fprintf(stderr, "Argument 1 is %s\n", my_string);

    process_args(my_string);
}

Вокруг все больше кода, поэтому я не могу попросить кого-нибудь отладить мою программу - я хочу знать, КАК я могу отладить, почему строки символов, подобные этой, меняют или перезаписывают свою память на основе несвязанного кода. Моя память ограничена? Мой стек слишком маленький? Как мне сказать? Что еще я могу сделать, чтобы отследить проблему? Моя программа не очень большая, она похожа на тысячу строк кода, которые дают или принимают, и пару динамически связанных внешних библиотек, но ничего необычного.

HELP! ТИА!

Ответы [ 4 ]

6 голосов
/ 17 мая 2010

Simple:

  1. Научитесь использовать Valgrind , в частности memcheck
  2. Научитесь использовать GDB , включая точки останова и переменную проверку
  3. Практика совершенствует.

Это должно сортировать это. Убедитесь, что вы скомпилировали все библиотеки с опцией -g в GCC, которая сохраняет символы отладки, чтобы ваш вывод отладки имел больше смысла.

2 голосов
/ 17 мая 2010

Необходимо рассмотреть два случая:

  1. Переменная arg изменяет значение между началом и концом process_args.
  2. arg остается тем же,но строка, на которую он указывает, изменена.

Ваше описание и ваш код не различают эти два, но важно знать, какое из двух на самом деле происходит.

Это откроет ответ:

fprintf(stderr, "Function arg is %s (%p)\n", arg, (void *)arg);
... do bunch of stuff ...
fprintf(stderr, "Function arg is now %s (%p)\n", arg, (void *)arg);

Чаще всего arg не меняется (т.е. у вас есть случай 2).Если это так, что-то портит выделенную вами строку.Valgrind, уже предложенный, но доступный только в Linux, AIX и MacOSX, имеет только 50:50 шанс найти проблему.То, что вы действительно хотите, - это точка наблюдения GDB: установите точку останова в начале process_args, после нажатия выполните (gdb) watch *(long*)arg и continue.GDB остановится, когда что-то запишется в *arg (фактически остановится при следующей инструкции).Затем используйте команду (gdb) where, чтобы выяснить, что происходит.

Если у вас на самом деле arg изменяется его значение (случай 1), это может быть сложнее для отладки, и указывает на повреждение стека какого-либо роданарушение правил вызова процедур для вашей платформы.Valgrind, скорее всего, не поможет с этим.Это больше соответствует поведению, которое вы описали: комментирование несвязанного кода приводит к смещению ошибки.

Хотя я не могу дать никаких дополнительных советов по отладке варианта 1, так как вы не раскрыли, что такое актуальная платформа.

1 голос
/ 17 мая 2010

Если вы пишете приложения уровня пользователя, Valgrind является хорошим выбором для обнаружения проблем с памятью, таких как утечки памяти, переполнение буфера и т. Д. Вот краткое руководство: http://valgrind.org/docs/manual/QuickStart.html

0 голосов
/ 17 мая 2010

Вы не предоставляете свои инструменты разработки, но если вы похожи на 90% программистов, вы уже используете IDE с отладчиком, который может справиться с этим, никаких новых инструментов не требуется. Установите часы на кусок памяти, в котором хранятся ваши строки, затем прокрутите код и посмотрите, когда строки будут изменены.

...