C programming: How to use gdb with Makefile and command line arguments? - c

To create the .out executable, I have to enter:
$: make
$: myprogram.out name.ged
My program incorporates a command line argument, thus the "name.ged".
Whenever I run gdb after getting a segmentation fault (core dumped), I enter:
$: gdb a.out core
(gdb): bt
I then use the back trace command, and gdb returns:
#0 0x4a145155 in ?? ()
#1 0x08a16ce0 in ?? ()
I even tried using the up command t move up the stack, but still no luck. I can't tell which line in my program is giving me the seg fault. gdb works with my other programs that do not involve a Makefile and command arguments, so I'm wondering if my commands are incorrect.

Summarizing the comments (before anyone else does :).
Your executable file is missing the symbolic information that gdb needs to display the relevant source code. You need to add the -g option to the compile command and produce a new executable. Then re-run your failing test to produce a new core file. gdb with this executable and core will be able to show you the stack of function calls using backtrace.
In a makefile, the easiest way to do this is to add (to) the CFLAGS variable which is used with the implicit .o.c rule.
CFLAGS= -g -Wall -Wextra
You can also add this directly to the command-line (assuming a decent shell :). This sets the value as an environment variable during the execution of the make command (and sub-commands).
$ CFLAGS='-g -Wall -Wextra' make
I'd actually recommend you add this to your bash .profile, so you always get the most information from the compiler.
CFLAGS='-Wall -Wextra'
Then, when you need it, put this in the makefile to make a debuggable executable:
CFLAGS+= -g

Related

How to disable all compilation arguments for gdb compile code command?

Following this process
from an earlier question (see answer).
gdb is a huge improvement over spim, but I'd like to use the compile code feature of gdb, to inject arbitrary mips instructions at the point of execution.
I have read Compiling and injecting code in gdb. When I run run compile code <anything>, I get the error "compilation failed, unrecognized argument -m32". Then when I run set debug compile in gdb, and I try compile code <anything> again, I see that the argument -m32 is passed to mips-linux-gnu-gcc.
I tried overriding the compilation arguments using set compile-args -march=mips32r3, which adds the compilation argument, but -m32 is still passed and still gives me an error.
How do I prevent -m32 from being passed? Is there a clean workaround (short of making a dummy script that strips -m32 before compiling?)
How do I prevent -m32 from being passed?
It looks like this is the case where GDB developers thought that "GDB knows better", and didn't provide any way to override this.
Specifically, the -m32 comes from default_gcc_target_options(), which unconditionally adds -m%d with gdb_arch_ptr_bit() as the argument.
Short of building your own GDB or providing a GCC wrapper that strips -m32, I don't see any way to get rid of this argument.
Make this script, special-gcc. Make it executable, chmod 777 special-gcc. The script uses exec to have the process replaced with the gcc invocation, as opposed to spawning a child process. Arguments are $#, stored in array, filtered in loop, then passed to the gcc invocation.
#!/bin/bash
declare -a args=()
#!/bin/bash
echo -- "----------------" >> ~/gcc-wrapper-log
for arg in "$#"
do
if ! [[ "$arg" == '-m32' ]]; then
echo -- "$arg" >> ~/gcc-wrapper-log
args+=("$arg")
fi
done
exec mips-linux-gnu-gcc -static "${args[#]}"
Inside gdb, run the command set compile-gcc /path/to/special-gcc. Attempt some command compile code <anything>. Then in gcc-wrapper-log you can see all the arguments to the compilation, can selectively disable them in the script.
For me, the compilation succeeded, but because I am using the mips-linux-gnu-gcc cross compiler binary, gdb seems not to link the resulting .o file correctly. See the docs for details on the internals of the compile code feature. Somewhere in the steps "Relocating the object file" is where the process failed for me for mips-linux-gnu-gcc.
However, this is still a clean and easy way to precisely control the compilation arguments used by gdb compile code.

How can I perform line by line crash debugging to deal with "has stopped working" error in c?

I have a c project compiled with GCC.When I run my test.exe program ends with "test.exe has stopped working" but compiled successfully.How can I debug my program and how can find where is my mistake?
Technique 1:
I tried to printf("Successful 1..."),printf("Successful 2...") on the beginning of every single line of code but this method is frustrating.Are there tools(gdb...) to debug my code line by line for me?
printf("Successful 1...")
//code
printf("Successful 2...")
//code
How can I debug my program line by line with GDB?
Can I go to the error line directly with GDB?
Edit 1:
I use gdb and type run command and get following output which is not helpful(segmentation fault but where?):
Starting program: C:\Users\q\..././bin/test.exe
[New Thread 3292.0x22b8]
[New Thread 3292.0x1fb8]
Program received signal SIGSEGV, Segmentation fault.
0x7696e3e3 in ungetwc () from C:\WINDOWS\SysWOW64\msvcrt.dll
Edit 2:
How to debug using gdb? doesn't contain helpful answer to my question.Not possible duplicate of my answer
Edit 3:(bt method output)
I have program that contain 6 source and 6 header files.And every header and source files contain three and more than function pointers that perform some action.I tried debug with gdb bt and get following output:
#1 0x00000001 in ?? ()
#2 0x00000073 in ?? ()
#3 0x00000032 in ?? ()
#4 0x00000000 in ?? ()
My makefile:
all: compile run
compile :
gcc -I ./include/ -o ./lib/... .o -c ./src/... .c
gcc -I ./include/ -o ./lib/... .o -c ./src/... .c
gcc -I ./include/ -o ./lib/... .o -c ./src/... .c
gcc -I ./include/ -o ./lib/... .o -c ./src/... .c
gcc -I ./include/ -o ./lib/... .o -c ./src/... .c
gcc -I ./include/ -o ./bin/test ./lib/... .o ./lib/... .o ./lib/... .o ./lib/... .o ./lib/... .o ./src/test.c
run:
gdb ./bin/test.exe
Sometimes, if your bug is particularly bad, it overwrites the stack and demolishes all the clues that gdb (and particularly the bt command) would need in order to show you where you were.
In that case you can try something like this:
Start gdb, set a breakpoint on main, run your program, wait for the breakpoint to be hit.
Single-step through your program with the n command, which steps over, not down into, functions. (That is, each called function runs all at once; you're not single-stepping recursively down into each function.) Sooner or later one of your single-steps will step over a function which crashes. Now you've narrowed it down a bit.
Set a breakpoint on that function.
Rerun the program.
When you hit the breakpoint inside the troublesome function, again begin single-stepping. Sooner or later one of your single-steps will enter a sub-function which crashes. Now you've narrowed it down a bit more.
Continue in this fashion until you've located the actual line causing the crash.
You are getting segmentation fault and that is why your application is not running. Segmentation fault is a run time problem, even if your program compiles successfully.
In gdb after you get this:
Program received signal SIGSEGV, Segmentation fault.
type bt. The gdb's bt command will show you the back trace of your running program. It tells you which flow your program took and also the exact line which caused the segmentation fault and made your application crash.
The output of bt will be more 'readable' if you have built your application in debug mode. If you are using using gcc, you need to add -g flag to build in debug mode

How can I pass two options to GCC when compiling my program?

I was doing a homework assignment and I wanted to use the <ncurses.h>. So the gcc filename.c -lncurses generates an assembler output and./a.out executes the code. In order to avoid ***stack smashing detected*** or segmentation fault error I also need to execute the gcc filename.c -fno-stack-protector. Is there any way through which I could execute both the commands on the terminal or the code could execute the -fno-stack-protector command?
ps : please go easy I am a complete noob :) :P
GCC can take multiple options on the command line. You should be able to pass any combination of -f and -l options, provided those options are compatible. You can get a great deal of information about the correct syntax for invoking GCC by running man gcc (or, on some systems, info gcc).
And, as I commented above, if you're getting a "stack smashing detected" error, the solution is not to pass -fno-stack-protector (which just disables the code GCC uses to detect these kind of bugs), but rather to fix the actual bug in your program that is causing the stack to get overwritten.

No source file named main.c. gdb break point setting

I am using gdb for debugging C project source code. I compile as shown:
./configure --enable-debug CFLAGS="-g -o0"
make --debug=a
I want to debugging stop at specific file. So when I set break point by using
(gdb) break main.c:672
It says:
No source file named main.c.
Even when I pass specific function name (in main.c file) to break . it says: such function not defined.
My current directory has this main.c file. I am using Cygwin on Windows. When I set break point by using
(gdb) break main
It set break point at a main function of Cygwin file, not in my source code.
how can I fix my first problem?
just curious, how to avoid second problem, if there is same function name within Cygwin files and my source code?
When you compile your .c file, make sure you use:
gcc filename.c -g
gdb <binary name>
Search for load debugging symbols done or not?
If not:
gdb) symbol-file <path-of-symbol-file>
you can find symbol file in obj directory
If you're compiling with -g and still not able to set a breakpoint, try adding raise(SIGTRAP) in your main(), run the process in gdb, then set the breakpoint you want again after it hits the SIGTRAP.
Crucial is gcc parameter -g during compilation.
Everything else is secondary.
See breakpoints in GDB
I also encountered with similar problem earlier. I just deleted .metadata folder and imported the particular project again and that work well.
Whenever you have to use GDB, type the following in command line
gcc -g -o outputfile sourcefile.c
Now type
gdb -tui outputfile
and then enter the break command

Using gcc with -g flag before running gdb

without -g flag:
(gdb) break main
Breakpoint 1 at 0x8048274
with -g flag:
(gdb) break main
Breakpoint 1 at 0x8048277: file example.c, line 31.
I vaguely know -g option stores the symbol table information.
What does the -g option exactly do?
Is there any way I can look at this symbol table?
-g (for gcc) stores debugging information in the output files so that debuggers can pick it up and present more useful information during the debugging process. Exactly what gets stored can depend a great deal on the environment you're running in.
One way to look at what this consists of is to use objdump with the --debugging option (or its equivalent short form -g which matches gcc).
The -g command line option asks the compiler to emit additional debugging information; on Linux, the format is DWARF 2, but other platforms may have different defaults -- stabs was more common, once upon a time.
readelf --debug-dump can be used to dump the debugging information itself if you're curious in what it adds -- you can see the entire program source in the .debug_info section, for example.

Resources