Несколько человек уже упоминали изменения времени. Даже если ваш код однопоточный, вы можете вызывать API, который либо запускает потоки от вашего имени, либо реализует какую-то другую форму асинхронного взаимодействия.
Что касается этого утверждения:
Трассировка - это кусок кода, поэтому следует перейти к сегменту кода
Это зависит от того, что на самом деле ваш код трассировки делает . Даже что-то простое, как:
write(0, "Hello, World!\n", 14);
По крайней мере добавит дополнительное хранилище данных для константной строки, что сместит расположение других постоянных данных и, возможно, изменит начало других сегментов памяти, влияя также на расположение кода и / или кучи. Если это первая ссылка на эту функцию, она добавит запись перемещения в объектный файл, что может вызвать другие сдвиги в разметке памяти.
Более сложный вызов трассировки, который, например, вызывает fwrite или printf, почти наверняка приведет к выделению некоторой памяти для временных буферов и т. Д.
Если вы можете воспроизвести ошибку (с исходным кодом, очевидно) при запуске в отладчике, то вы должны быть в состоянии по крайней мере определить, какой код вызывает ошибку segfault. Если отладчик также приводит к тому, что ошибка не возникает, вы можете рассмотреть возможность включения дампов ядра и отладки на основе дампа.
Если это не удастся, вы можете попробовать запустить код с отладочным пакетом malloc (доступно несколько). Даже если «ошибка» не воспроизводится, вы, скорее всего, обнаружите некоторые неправильные манипуляции с указателем.
Последнее предложение: перекомпилируйте ваш код со всеми предупреждениями, включенными в компиляторе, и серьезно рассмотрите все сгенерированные предупреждения. Обратите внимание, что при gcc -Wall не включает все предупреждения.