A couple of folks have already mentioned timing changes. Even if your code is single-threaded, you might be calling API that either starts threads on your behalf, or implements some other form of asynchronous communication.
As far as this statement is concerned:
The trace line is a piece of code so should go to the code segment
That depends on what your tracing code actually does. Even something as simple as:
write(0, "Hello, World!\n", 14);
Will at the least add additional data storage for the constant string, which will shift the location of other constant data, and possibly change the start of other memory segments, affecting the location of code and/or heap, as well. If this is the first reference to that function, it'll add a relocation record to the object file, which might cause other shifts in the memory layout.
A more-complex tracing call that calls fwrite or printf, for example, will almost certainly end up allocating some memory for temporary buffers, etc.
If you can reproduce the bug (with the original code, obviously) when running in the debugger, then you should be able to at least determine which code is triggering the segfault. If the debugger also causes the bug not to happen, you might consider enabling core dumps, and debugging based on the dump.
Failing that, you can try running the code with a debugging malloc package (there are several available). Even if "the bug" doesn't reproduce, you'll likely find some improper pointer manipulation that way.
Last suggestion: Re-compile your code with all warnings enabled on the compiler, and seriously consider all of the warnings so generated. Note that with gcc, -Wall does not turn on all warnings.