2015-03-29 5 views
0

Он работает, когда в цикле я устанавливаю каждый элемент в 0 или в entry_count-1. Он работает, когда я устанавливаю его так, чтобы entry_count был маленьким, и я пишу его вручную, а не по циклу (sorted_order [0] = 0; sorted_order [1] = 1; ... и т. Д.).Как отладить ошибку сегментации?

Пожалуйста, не говорите мне, что делать, чтобы исправить мой код. Я не буду использовать интеллектуальные указатели или векторы по очень конкретным причинам. Вместо этого сосредоточьтесь на вопросе: Какие условия могут вызвать этот segfault? Спасибо.

---- OLD -----

Я пытаюсь отлаживать код, который не работает на компьютере UNIX. Суть этого кода заключается в следующем:

int *sorted_array = (int*)memory; 
// I know that this block is large enough 
// It is allocated by malloc earlier 

for (int i = 0; i < entry_count; ++i){ 
    sorted_array[i] = i; 
} 

Кажется, что segfault находится где-то в цикле. К сожалению, переход в режим отладки делает остановку segfault. Используя отладку cout, я обнаружил, что она должна быть в цикле.

Далее я хотел бы знать, как далеко в этом цикле СЛУЧИЛОСЬ так выдаёт ошибку сегментации я добавил:

std::cout << i << '\n'; 

Он показал весь диапазон был, предполагают, чтобы быть зацикливание снова и не было выдаёт ошибку сегментации.

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

Я пробовал некоторые другие разнообразные операции, пытаясь выяснить, что происходит. Я попытался установить переменную j = i; и тому подобное, но я ничего не нашел.

Запуск valgrind Единственная информация, которую я получил на segfault, состояла в том, что это была «ошибка общей защиты» и что-то вроде ответа по умолчанию на 11. В нем также упоминается, что есть условный переход или перемещение зависит от неинициализированных значений, но, глядя на код, я не могу понять, как это возможно.

Что это может быть? У меня нет идей для изучения.

+1

Что говорит вам отладчик? Как вы знаете, что блок достаточно велик? Как это было выделено? С этого момента изменился ли параметр 'entry_count'? Почему вы не используете 'std :: vector'? –

+1

Нам нужно увидеть больше кода. Предполагая, что 'int * memory = new int [entry_count]', тогда все должно быть ОК. Или загрузите файл «core» в gdb и покажите нам вывод 'where' и' bt full'. Наконец, вы должны использовать 'new' или better,' std :: vector'. – jww

+1

Ничто в коде, которое вы предоставили, не должно указывать на segfault, если ваши предположения о 'memory' правильны. Я предлагаю использовать 'std :: vector', который будет проверяться на хороших компиляторах отладки и, вероятно, немедленно покажет вашу проблему. –

ответ

0

Это сложно, я использовал valgrind инструменты для отладки seg-faults и обычно указывал на нарушения.

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

+0

Вы использовали memgrind с проверкой границ? Memcheck Memcheck обнаруживает проблемы управления памятью и ориентирован прежде всего на программы на C и C++. Когда программа запускается под наблюдением Memcheck, все проверки и записи памяти проверяются, а вызовы malloc/new/free/delete перехватываются. В результате Memcheck может обнаружить, ваша программа ... – iceraj

+0

Я никогда не слышал об этом. Я использовал memcheck, который был единственным вариантом, который я установил. –

+0

Существует множество опций [Memcheck: детектор ошибок памяти] (http://valgrind.org/docs/manual/mc-manual.html#mc-manual.errormsgs). Я нашел --malloc-fill и -free-fill полезным. Кроме того, если вы можете опубликовать отчет mc, который поможет. – iceraj

3

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

Однако, как вы упомянули в своем вопросе, что вы можете прикрепить свою программу, используя Valgrind. как есть воспроизводимый. Таким образом, вы можете захотеть прикрепить свою программу (a.out).

$ valgrind --tool = memcheck --db-attach = yes ./a.out

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

Как только вы сможете понять свою первую ошибку, исправьте ее и запустите ее и посмотрите, какие другие ошибки вы получаете. Эти шаги должны быть выполнены до тех пор, пока Valgrind не сообщит об ошибке.

Однако вам следует избегать использования исходных указателей в современных программах на C++ и начать использовать std::vector std::unique_ptr, как это было предложено и другими.

2

Valgrind и GDB очень полезны.

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

Вот некоторые ресурсы, которые могут направить вас на использование GDB:

GDB Tutorial 1

GDB Tutorial 2

Если вы до сих пор не можете понять, как использовать GDB с этими учебниками, есть тонны на Google! Просто выполните поиск отладки с ошибками сегментации с помощью GDB!

Удачи :)

0

Через несколько дней экспериментов я понял, что происходит на самом деле.

По какой-то причине машина segfaults на несвязанный доступ. То есть целые числа, которые я писал, не записывались на границы памяти, которые были кратными четырем байтам. Перед петлей я вычислен смещением и сдвинут массив до, что много:

int offset = (4 - (uintptr_t)(memory) % 4) % 4; 
memory += offset; 

После выполнения этого все вели себя, как ожидается, снова.