Подтвердить что ты не робот

Сбой обычно, но не с GDB?

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

4b9b3361

Ответ 1

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

Ответ 2

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

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

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

Ответ 3

Звучит как Heisenbug, который у вас есть: -)

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

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

Ответ 4

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

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

Ответ 5

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

Ответ 6

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

Ответ 7

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

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

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

Ответ 8

У меня была аналогичная проблема, в моем случае она была связана с указателями в структуре связанных ссылок. Когда я динамически создавал новый список без инициализации всех указателей внутри структуры, моя программа вылетает наружу 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;
}

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

Ответ 9

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