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

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.

Related

Passing arguments from my bash script into a c program

Im trying to use one of the inputs from my bash script into my c program and i just dont know how to do so.
What command should i add for the argument to be passed on to my c program?
Thanx
My script is -
bash script
I guess that you want to pass the argument to prog.exe and not to gcc, then
gcc -c -g -Wall calc_statistics.c gcc -o prog.exe && ./prog.exe "$1"
That is, compile the program and if there are no error run it with the argument.
It's not very efficient to compile the program every time the script runs so you can move gcc out.
You can also check your script using shellcheck.

Alias or command to compile and link all C files

I recently started compiling/linking my C files by hand using the gcc command. However it requires all of the source files to be typed at the end of the command. When there are many files to compile/link it can be boring.
That's why I had the idea of making a bash alias for the command which would directly type all *.h and *.c files of the folder.
My line in .bashrc is this:
alias compile='ls *.c *.h | gcc -o main'
I found it to work some times but most of the time compile will return this :
gcc: fatal error: no input files
compilation terminated.
I thought that pipe would give the results of ls *.c *.h as arguments to gcc but it doesn't seem to work that way. What am I doing wrong? Is there a better way to achieve the same thing?
Thanks for helping
A pipe does not create command line arguments. A pipe feeds standard input.
You need xargs to convert standard input to command line arguments.
But you don't need (or want) xargs or ls or standard input here at all.
If you just want to compile every .c file into your executable then just use:
gcc -o main *.c
(You don't generally need .h files on gcc command lines.)
As Kay points out in the comments the pedantically correct and safer version of the above command is (and I don't intend this in a pejorative fashion):
gcc -o main ./*.c
See Filenames and Pathnames in Shell: How to do it Correctly for an extensive discussion of the various issues here.
That being said you can use any of a number of tools to save you from needing to do this and from needing to rebuild everything when only some things change.
Tools like make or its many clones, "front-ends" (e.g. the autotools, cmake) or replacements (tup, scons, cons, and about a million other tools).
Have you tried using a makefile? It sounds like that might be more efficient for what you're trying to do.
If you really want to do it with BASH aliases, you have to use xargs to get standard input to command line arguments.
There are several misconceptions here:
the pipe redirects the standard output of the first command to the standard input of the second command; however, gcc doesn't accept the files to compile on stdin, but on the command line;
the wildcard syntax is not something that is magical just to ls, it's the shell that performs their expansion on the command line;
header files are not to be compiled - you compile .c files, which in turn may include headers.
Armed with this knowledge, you'll understand that the correct command something like
gcc -o main *.c
Actually we can do better: first of all, you'll want to change the *.c to ./*.c; this prevents files whose name start with a - from being interpreted as command line options.
Most importantly, you should really enable the compiler warnings, they can be life saver. You'll want to add -Wall and -Wextra.
gcc -Wall -Wextra -o main ./*.c
Finally, it's worth saying that by default you are compiling with optimizations disabled. If you are debugging that's OK, but you want also to add -g to have an executable usable in debugging; otherwise, if the target is speed you should at least add -O2.

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

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

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

Resources