Вылетает нормально, но не с GDB? - PullRequest
21 голосов
/ 22 сентября 2011

Моя программа падает с ошибкой сегментации при нормальном запуске.Поэтому я запускаю его с помощью GDB, но он не вылетает, когда я это делаю.Кто-нибудь знает, почему это может произойти?Я знаю, что Faq Valgrind упоминает об этом (не сбой при valgrind), но я не мог найти ничего об этом, связанных с GDB в GoogleЕсли кто-то может сказать мне, почему, или порекомендовать что-то искать, когда это произойдет, я был бы очень благодарен.

Ответы [ 9 ]

15 голосов
/ 22 сентября 2011

Раньше такое случалось со мной (вы не одиноки), но я не могу вспомнить, что я сделал, чтобы все исправить (я думаю это было двойное освобождение).

Мое предложение было бы настроить вашу среду для создания дампов ядра, а затем использовать GDB для исследования дампов ядра после сбоя программы.В bash это делается с ulimit -c size, где размер может быть любым;Я лично использую 50000 для максимального размера 25 МБ;единица измерения с шагом 512 байт.

Вы можете использовать GDB для исследования дампа ядра, используя gdb program core.

7 голосов
/ 22 сентября 2011

Похоже на Гейзенбаг у вас есть: -)

Если платформа, с которой вы работаете, способна создавать файлы ядра, должна быть возможность использовать файл ядра и gdb для определения места, где происходит сбой программы - краткое объяснение можно найти здесь .

Пусть это будет несколько раз сбой, хотя, когда сбой вызван разрушением стека или перезаписью переменной, может показаться, что ошибка "обходит".

3 голосов
/ 22 сентября 2011

Ну, я отследил это до вызова pthread_detach.Я делал pthread_detach (& thethread).Я просто забрал ссылку и изменил ее на pthread_detach (thethread), и она работала нормально.Я не уверен, но, возможно, это было двойное освобождение, отсоединив ссылку, а затем снова уничтожив ее, когда она вышла из области видимости?

2 голосов
/ 22 сентября 2011

Попробуйте подключиться к запущенному процессу в gdb, продолжая, а затем воспроизводя сбой. Другими словами, не запускайте программу в пределах gdb; вместо этого запустите программу как обычно, а затем attach <pid>.

Иногда при индивидуальном шаге по линиям условие гонки, приводящее к аварийному завершению программы, не проявляется, поскольку опасность гонки исключена или сделана крайне маловероятной из-за «длительных» пауз между шагами.

1 голос
/ 22 сентября 2011

Проверьте возвращаемое значение pthread_detach вызова. Согласно вашему ответу , вы, вероятно, передаете неверный дескриптор потока в pthread_detach.

0 голосов
/ 21 ноября 2017

У меня просто была похожая проблема, в моем случае она была связана с указателями в моей структуре данных связанного списка. Когда я динамически создал новый список без инициализации всех указателей внутри структуры, моя программа вылетает за пределы GDB

Вот мои оригинальные структуры данных:

typedef struct linked_list {
    node *head;
    node *tail;
} list;

typedef struct list_node {
    char *string;
    struct list_node *next;
} node;

Когда я создал новый "экземпляр" list, указав его head и tail, программа вылетала за пределы DGB:

list *createList(void) {
    list *newList = (list *) malloc(sizeof(list));
    if (newList == NULL) return;

    return newList;
}

Все стало нормально работать после того, как я изменил свою функцию createList на эту:

list *createList(void) {
    list *newList = (list *) malloc(sizeof(list));
    if (newList == NULL) return;

    newList->head = (node *) 0;
    newList->tail = (node *) 0;

    return newList;
}

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

0 голосов
/ 08 октября 2014

У меня тоже такое случалось со мной несколько раз.

Мое решение: очистить и восстановить все.

Не сказать, что это всегда решает все проблемыв случае с OP проблема была на 1007 * действительно неправильной), но вы можете сэкономить немного времени и усилий, если сделаете это первым, столкнувшись с такими действительно странными «мета» ошибками.По крайней мере, по моему опыту, такие вещи чаще всего происходят из старых объектных файлов, которые должны были быть восстановлены, но не были.И в MinGW, и в обычном GCC.

0 голосов
/ 22 сентября 2011

Когда вы запускаете код с помощью GDB, он перемещается.Теперь нелегальный адрес, на который вы пытались сослаться ранее - тот, который вызвал segfault - внезапно стал законным.Это боль, конечно.Но лучший способ, с помощью которого я могу отследить этот тип ошибки, - это начинать использовать printf () повсюду, постепенно сужая его.

0 голосов
/ 22 сентября 2011

Если ошибка зависит от времени, GDB может предотвратить его повторение.

...