Determine the line of code that causes a segmentation fault?
GCC can't do that but GDB (a debugger) sure can. Compile you program using the -g
switch, like this:
gcc program.c -g
Then use gdb:
$ gdb ./a.out
(gdb) run
<segfault happens here>
(gdb) backtrace
<offending code is shown here>
Here is a nice tutorial to get you started with GDB.
Where the segfault occurs is generally only a clue as to where "the mistake which causes" it is in the code. The given location is not necessarily where the problem resides.
How to find the line caused segmentation fault in c++ compiled program
When compiling the program, add the -g
compiler flag, or even better -ggdb3
, which will give you a much prettier output, by adding debugging symbols to the executable. Also, make sure that you compile with the -O0
optimization level.
To actually debug the program, run gdb ./main.out
to start the program in a debugging session. If you then run r
, gdb will start executing the program, and then stop at the line that gives the segfault.
To figure out how you got to that point, run bt
while in the debugging session, and you will get a backtrace, which will show you all the function calls that were made to get to the line of code that crashed.
You can of course do a lot more than this (and you will probably need to, since locating the source of an error is often only the first step). You can use p
to print the values of variables, set watchpoints, and many more things. For a while now, gdb even ships with a full fledged python interpreter, so you can even write a python script for your custom debugging needs.
Learning how to use gdb can seem overwhelming at the start, but persevere, and I guarantee the effort will pay off big time :)
Segmentation Fault before even the first line of `main()` is executed and there are no non-local variables
This is definitely a stack overflow. sizeof(dynamic_loop_functor_t)
is nearly 64 MiB, and the default stack size limit on most Linux distributions is only 8 MiB. So the crash is not surprising.
The remaining question is, why does the debugger identify the crash as coming from inside std::operator<<
? The actual segfault results from the CPU exception raised by the first instruction to access to an address beyond the stack limit. The debugger only gets the address of the faulting instruction, and has to use the debug information provided by the compiler to associate this with a particular line of source code.
The results of this process are not always intuitive. There is not always a clear correspondence between instructions and source lines, especially when the optimizer may reorder instructions or combine code coming from different lines. Also, there are many cases where a bug or problem with one source line can cause a fault in another section of code that is otherwise innocent. So the source line shown by the debugger should always be taken with a grain of salt.
In this case, what happened is as follows.
The compiler determines the total amount of stack space to be needed by all local variables, and allocates it by subtracting this number from the stack pointer at the very beginning of the function, in the prologue. This is more efficient than doing a separate allocation for each local variable at the point of its declaration. (Note that constructors, if any, are not called until the point in the code where the variable's declaration actually appears.)
The prologue code is typically not associated with any particular line of source code, or maybe with the line containing the function's opening
{
. But in any case, subtracting from the stack pointer is a pure register operation; it does not access memory and therefore cannot cause a segfault by itself. Nonetheless, the stack pointer is now pointing outside the area mapped for the stack, so the next attempt to access memory near the stack pointer will segfault.The next few instructions of
main
execute thecout << "Starting main"
. This is conceptually a call to the overloadedoperator<<
from the standard library; but in GCC's libstdc++, theoperator<<
is a very short function that simply calls an internal helper function named__ostream_insert
. Since it is so short, the compiler decides to inlineoperator<<
intomain
, and somain
actually contains a call to__ostream_insert
. This is the instruction that faults: the x86call
instruction pushes a return address to the stack, and the stack pointer, as noted, is out of bounds.Now the instructions that set up arguments and call
__ostream_insert
are marked by the debug info as corresponding to the source ofoperator<<
, in the<ostream>
header file - even though those instructions have been inlined intomain
. Hence your debugger shows the crash as having occurred "inside"operator<<
.Had the compiler not inlined
operator<<
(e.g. if you compile without optimization), thenmain
would have contained an actual call tooperator<<
, and this call is what would have crashed. In that case the traceback would have pointed to thecout << "Starting main"
line inmain
itself - misleading in a different way.
Note that you can have GCC warn you about functions that use a large amount of stack with the options -Wstack-usage=NNN
or -Wframe-larger-than=NNN
. These are not enabled by -Wall
, but could be useful to add to your build, especially if you expect to use large local objects. Specifying either of them, with a reasonable number for NNN
(say 4000000), I get a warning on your main
function.
SEGMENTATION FAULT for my code , need guidance with debugging
Seem very likely to me that this code
if(i>0)
{
x+="U";
rat(m,n,ans,i-1,j);
}
x.pop_back();
should be
if(i>0)
{
x+="U";
rat(m,n,ans,i-1,j);
x.pop_back();
}
Same error several times.
The way you have written it, you will remove characters from x
that were never put there in the first place.
Is segmentation fault caused from fopen line a stack overflow problem in C? (darknet, detector.c)
fopen
returns a file handle. Just a couple lines above you're defining a variable FILE *log_csv;
which would be probably where you want to put that handle.
Furthermore the second argument of fopen
is a C-string (i.e. a pointer to a NUL terminated array of chars). TTBT, I'm surprised your compiler did let this pass.
Try this:
FILE *log_csv = fopen("/home/aicar/darknet/0_log_ju0.csv", "a");
if( !log_csv ){
printf("failed to open csv file\n\n");
exit(1);
} else {
printf("%d\n", fileno(log_csv));
…
}
Related Topics
Undefined Behavior and Sequence Points Reloaded
Global Memory Management in C++ in Stack or Heap
Fastest Way to Determine If an Integer Is Between Two Integers (Inclusive) With Known Sets of Values
Fixed-Size Floating Point Types
Move Assignment Operator and 'If (This != &Rhs)'
Why Do We Use Volatile Keyword
Create Registry Entry to Associate File Extension With Application in C++
Best C++ Ide or Editor For Windows
Using Opencv and Svm With Images
C++11 Reverse Range-Based For-Loop
Std::Cin.Getline( ) Vs. Std::Cin
Cmake Cannot Find Library Using "Link_Directories"