I start gdb using this (working dir is /home/leon/Develop/tests/atomic/):
gdb ./bin/lin64/httpress
Then I add directories with source files, and it understands me:
Source directories searched: /home/leon/Develop/tests/atomic/third/http_parser:/home/leon/Develop/tests/atomic/src/tools:$cdir:$cwd
When I run my binary, gdb doesn't recognize the line in my source code, where segfault happened.
How to set source files for gdb?
The program is compiled by gcc:
gcc -D_AMD64_ -D_LIN_ -D_LARGEFILE64_SOURCE -D_GNU_SOURCE -m64 -march=core2 -O2 -Wall -I. -I src/include -I src/lib/zlib/ -I src/lib/otg -I third/openssl/include/ -I src/lib/otg/Tools/HostTime/Interfaces/ -I src/lib/otg/Tools/OpenToolsGate/Guest/Interfaces/ -I src/lib/otg/Tools/OpenToolsGate/Guest/Cross -I src/lib/otg/Tools/OpenToolsGate/Common/Interfaces/ -o bin/lin64/httpress -std=c99 -lpthread -lev -lgnutls -O2 -s -DWITH_SSL -Wno-strict-aliasing \
-I /usr/include/libev src/tools/httpress.c -I third/http_parser/ third/http_parser/http_parser.c
Ok, I've made some changes:
gcc -g -ggdb -D_AMD64_ -D_LIN_ -D_LARGEFILE64_SOURCE -D_GNU_SOURCE -m64 -march=core2 -Wall -I. -I src/include -I src/lib/zlib/ -I src/lib/otg -I third/openssl/include/ -I src/lib/otg/Tools/HostTime/Interfaces/ -I src/lib/otg/Tools/OpenToolsGate/Guest/Interfaces/ -I src/lib/otg/Tools/OpenToolsGate/Guest/Cross -I src/lib/otg/Tools/OpenToolsGate/Common/Interfaces/ -o bin/lin64/httpress -std=c99 -lpthread -lev -lgnutls -s -DWITH_SSL -Wno-strict-aliasing \
-I /usr/include/libev src/tools/httpress.c -I third/http_parser/ third/http_parser/http_parser.c
In this case it still can't find symbols in the binary.
But if I remove -s option from gcc call. It writes:
Reading symbols from /home/leon/Develop/tests/atomic/bin/lin64/httpress...done.
But the debugger still says this:
(gdb) info source
No current source file.
...after I point him directories with sources.
You miss the -g in your gcc call to include debugging information.
On the other hand, I suggest to decrease optimization level from -O2 to -O0 and use it only once (included gcc call has 2 -O2).
Apart of this, you can add directories to gdb's source path with dir command: Source_Path. But this would only work if you've proper debug information available in httpress
But the debugger still says this:
(gdb) info source
No current source file.
...after I point him directories with sources.
This is expected. There is no current source because you haven't started executing your binary yet.
You want to start or run your binary and get it to some place in execution (e.g. main, or the crash point).
Remove optimize flag :
-O2
And add that flags:
-g -ggdb
Related
I am trying to use the FFMPEG library that I just compiled on Windows using MinGW in a C program in Eclipse. I have managed to build a simple HelloJNI.c file and run it:
gcc $(INCLUDES) -c -g -w HelloJNI.c
gcc -shared -o $(BIN_DIR)/hello.dll HelloJNI.o
I am now trying to compile a ffmpeg_native.c file that uses FFMPEG but I am getting errors running the following:
LIBRARY_PATH = -L:"c:/Dev/msys-1.0/local/lib" -L:"c:/Dev/msys-1.0/local"
INCLUDES = -I$(SRC_DIR) -I"c:/Dev/msys-1.0/local/include" -I"c:/Program Files/Java/jdk1.8.0_45/include" -I"c:/Program Files/Java/jdk1.8.0_45//include/win32"
BIN_DIR = ../bin
gcc $(INCLUDES) -c -g -w ffmpeg_native1.1.4.c
gcc -shared -o $(BIN_DIR)/exportnative.dll ffmpeg_native1.1.4.o $(LIBRARY_PATH) -lffmpeg -lavcodec -lx264 -lavformat -lavutil -lswscale
The first line runs fine but the second shows this output:
c:/Dev/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.9.3/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lavcodec
[etc for all libraries]
I am puzzled as I am able to run the following in MinGW with success:
ld -o /local/libffmpeg.so -L/local/lib -lavcodec -lx264 -lavformat -lavutil -lswscale
It cannot find library path since -L is missing before $(LIBRARY_PATH). From gcc man:
-Ldir Add directory dir to the list of directories to be searched for -l.
So, if LIBRARY_PATH contains directory with needed libraries and everyting other is fine the following should work:
gcc -shared -o $(BIN_DIR)/exportnative.dll ffmpeg_native1.1.4.o -L$(LIBRARY_PATH) -lffmpeg -lavcodec -lx264 -lavformat -lavutil -lswscale
It is not needed to put colon : between -L and the path. The following list should be added to the command line:
-L"c:/Dev/msys-1.0/local/lib" -L"c:/Dev/msys-1.0/local"`
Note that it is better to use some other environment variable name for building the command line, since LIBRARY_PATH is used by gcc directly:
LIBRARY_PATH
The value of LIBRARY_PATH is a colon-separated list of directories,
much like PATH. When configured as a native compiler, GCC tries the
directories thus specified when searching for special linker files, if
it can't find them using GCC_EXEC_PREFIX. Linking using GCC also uses
these directories when searching for ordinary libraries for the -l
option (but directories specified with -L come first).
I have the following code:
gcc -Wall -fno-stack-protector -O2 -g -fPIC -c ec.c
pwd
gcc -shared -Wl,-soname,libec.so.1 -o libec.so.1.0 ec.o /urs/src/soem/ethercat*.o ../soem/nicdrv.o -lc -lpthread
mv libec.so.1.0 /usr/lib/.
cd /usr/lib
ldconfig -v -n
ln -sf libec.so.1.0 libec.so
ln -sf libec.so.1.0 libec.so.1
It gives the following error when compiling:
/home/ebox/Documents/SVN/Libs/ec
gcc: error: /urs/src/soem/ethercat*.o: No such file or directory
mv: cannot stat ‘libec.so.1.0’: No such file or directory
I understand there is something wrong with the gcc command, but cannot figure out how to fix this. There are several .o files in the path that start with ethercat*.
How can I get this fixed?
The error means that there are no files that match the pattern /urs/src/soem/ethercat*.o.
Note that the first component is urs. Probably it should be usr.
If you have a simple C program, like
int main(void) {return 0;}
It can be compiled with gcc -o test test.c.
As I understand, gcc performs compiling, assembling then linking. The latter two steps are achieved by it running as and ld.
I can generate the assembly code by using gcc -S test.c.
What would you type into a terminal, to convert the assembly code into an executable?
(the reason for doing so is to learn assembly)
These are the different stages using gcc
gcc -E --> Preprocessor, but don't compile
gcc -S --> Compile but don't assemble
gcc -c --> Preprocess, compile, and assemble, but don't link
gcc with no switch will link your object files and generate the executable
// main.c
#include <stdio.h>
int main(void)
{
printf("Hello World !\n");
return 0;
}
For preprocessing, compiling, assembling and then finally linking the simple aforementioned hello world program, follow the steps below:
Step 1/4) Preprocess main.c to generate main.i:
$: gcc -E main.c -o main.i
NOTE: You could call the C preprocessor directly as well:
$: cpp main.c -o main.i
Step 2/4) Compile main.i to generate main.s:
$: gcc -S main.i -o main.s
Step 3/4) Assemble main.s to generate main.o:
$: as main.s -o main.o
NOTE: You can combine the aforementioned steps 1, 2 and 3 by using the -c (small C) flag of gcc:
$: gcc -c main.s -o main.o // OR $: gcc -c main.c -o main.o
Step 4/4) Link main.o with other necessary object files namely, crti.o & crtn.o (they define function prologs & epilogs, respectively), crt1.o (contains _start symbol for bootstrapping the initial execution of the program), libc.so path or -lc flag for libc and then finally set the name of the dynamic linker, to generate a dynamically linked ELF executable:
On x86_64:
$: ld /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/x86_64-linux-gnu/crtn.o /usr/lib/x86_64-linux-gnu/crt1.o -lc main.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o main_ELF_executable
OR (if you'd like to specify path to libc.so)
$: ld /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/x86_64-linux-gnu/crtn.o /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/libc.so main.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o main_ELF_executable
On 32-bit ARM:
$: ld /usr/lib/arm-linux-gnueabihf/crti.o /usr/lib/arm-linux-gnueabihf/crtn.o /usr/lib/arm-linux-gnueabihf/crt1.o -lc main.o -dynamic-linker /lib/ld-linux.so.3 -o main_ELF_executable
OR (if you'd like to specify path to libc.so)
$: ld /usr/lib/arm-linux-gnueabihf/crti.o /usr/lib/arm-linux-gnueabihf/crtn.o /usr/lib/arm-linux-gnueabihf/crt1.o /usr/lib/arm-linux-gnueabihf/libc.so main.o -dynamic-linker /lib/ld-linux-armhf.so.3 -o main_ELF_executable
You can then run the ELF executable 'main_ELF_executable':
$: ./main_ELF_executable
Hello World !
Sources:
https://linux.die.net/man/1/gcc
https://linux.die.net/man/1/ld
https://dev.gentoo.org/~vapier/crt.txt
gcc test.s -o test will compile the test from test.s for you.
NASM might also be worth your time -- it might be easier / more friendly than gcc for compiling assembly.
After you do gcc -S -o test.s test.c, type gcc -o test test.s.
As you may or may not know, the four stages of compilation are to preprocess (-E), compile to assembly (-S), assemble to object code (-c), and finally link. The hardest for me to figure out was how to use the preprocessor output. Here's how to do it:
gcc -E hello.c | gcc -S -xc -o hello.s -
gcc -c hello.s -o hello.o
gcc hello.o -o hello
You can have gcc start and stop the compilation process wherever you want. gcc test.s -o test will have it compile test.s from assembly into an executable.
what I did was first I run the preprocessor by
clang++ test.cpp -E > test.i
then compiled it with ...
clang++ -S test.i
it should create a assembly file test.s ... then make the machine insturction file by
as test.s -o test.o
now you need to link it which is kinda confusing for dumb peoples like me ...
so we don't know the arguments for our last process which is linking ... to find out ... run
clang++ -v test.s
it should give you some big text of something ... find this line "-dynamic-linker" ... there's definately a -dynamic-linker in your output text ... now copy the text from -dynamic-linker to rest of the output ... just copy everything afterwards including "-dynamic-linker" ... now what i got is ...
-dynamic-linker /system/bin/linker -o a.out /data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib/crtbegin_dynamic.o -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0 -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../.. -L/data/data/com.termux/files/usr/lib -L/system/lib /data/data/com.termux/files/usr/tmp/test-169b42.o -lc++_shared -lgcc -ldl -lm -lc -lgcc -ldl /data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib/crtend_android.o
in this what you have to change is where your object file is ... in my case it is /data/data/com.termux/files/usr/tmp/test-169b42.o ... i need to change it to where my test.o file is ... /data/data/com.termux/files/home/CPP/Cpp_Log/hello_world/test.o ... this is where my test.o file is ...
so the argument we have to pass is ...
-dynamic-linker /system/bin/linker -o a.out /data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib/crtbegin_dynamic.o -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0 -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../.. -L/data/data/com.termux/files/usr/lib -L/system/lib /data/data/com.termux/files/home/CPP/Cpp_Log/hello_world/main.o -lc++_shared -lgcc -ldl -lm -lc -lgcc -ldl /data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib/crtend_android.o
now to link ... use the ld ... so the command is ld args -o test or in our case ...
ld -dynamic-linker /system/bin/linker -o a.out /data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib/crtbegin_dynamic.o -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0 -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../.. -L/data/data/com.termux/files/usr/lib -L/system/lib /data/data/com.termux/files/home/CPP/Cpp_Log/hello_world/main.o -lc++_shared -lgcc -ldl -lm -lc -lgcc -ldl /data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib/crtend_android.o -pie -o test ...
since andriod 5+ can only run pie elf executables ... i also added the "-pie" (position independent executable) before the -o test ...
now it should give you a executable file test ... just run it by ./test
it should work
I have a very basic question. I did look around like over here http://www.cs.cmu.edu/~gilpin/tutorial/ but still doubtfull..
Consider the following makefile(had also given it in a previous question)
all: clients.so simulator backup
LD_PRELOAD=/home/Juggler/client/clients.so ./simulator
backup: backup.c libclient.a
gcc backup.c -o backup -L /home/Juggler/client -L. -lclient -ldl
simulator: simulator.c libclient.a
gcc -g simulator.c -o simulator -L /home/Juggler/client -L. -lclient -ldl -pthread
libclient.a: libclient.o client.o
ar rcs libclient.a libclient.o client.o
libclient.o:libclient.c
gcc -c libclient.c -o libclient.o -pthread
clients.so: client.o client_invoke.o
ld -shared -o clients.so client_invoke.o client.o -ldl
client_invoke.o: client_invoke.c
gcc -Wall -fPIC -DPIC -c -g client_invoke.c
client.o: client.c
gcc -Wall -fPIC -DPIC -c -g client.c -ldl -pthread
What do I do/change to debug using either gdb or valgrind. Actually I am getting a segmentation fault while doing make and would like to debug. But I have never used gdb or valgrind from within a makefile
Thanks
I made a small edit to your presentation. You originally wrote
client.o: client.c gcc -Wall -fPIC -DPIC -c -g client.c -ldl -pthread
Can you change it to the new form and see if make segfaults?
normally I would do something to the effect of:
$(DEBUGGER) ./simulator
then
$ make DEBUGGER=gdb --args
$ make DEBUGGER=valgrind
$ make # should still work without the debugger.
(technically the --args isn't needed for the command like it is, but if you add arguments to simulator in the future.)
but using LD_PRELOAD complicates this, because you probably don't want gdb loading libclient
gdb -ex 'set env LD_PRELOAD=/home/Juggler/client/clients.so' -ex 'run' ./simulator
Additionally its normal to link shared libraries through gcc via gcc -shared -o client.so
One inelegant way would be to spawn the process via the makefile, and then attach to it with GDB in another terminal. Using the trick from linux: suspend process at startup, you can launch the process and have it suspend immediately, and then connect with gdb.
have a script called launch.sh:
#!/bin/bash
echo "Pid is $$"
echo -n "Press Enter.."
read
exec $#
have a makefile recipe like this:
whatever_target: whatever_deps
./launch.sh PROGRAM [ARGS]
if for some reason you can't see the output (like if you are redirecting), you can still get the PID via ps -ef or something. then with gdb:
gdb PROGRAM_NAME PID
I'm getting a totally bizzare error trying to compile a C program using GCC. Here is the batch file I am using:
echo Now compiling, assembling, and linking the core:
nasm -f aout -o start.o start.asm
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o consoleio.o consoleio.c
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o core.o core.c
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o system.o system.c
ld -T link.ld -o core.bin start.o core.o system.o consoleio.o
echo Done!
concat.py
pause
Here are the error messages I am receiving when trying to run this code. All files are in the same directory, yes the PATH variable is set up correctly:
C:\Simple\core>build.bat
C:\Simple\core>echo Now compiling, assembling, and linking the core:
Now compiling, assembling, and linking the core:
C:\Simple\core>nasm -f aout -o start.o start.asm
C:\Simple\core>gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-func
tions -nostdinc -fno-builtin -I./include -c -o consoleio.o consoleio.c
The system cannot execute the specified program.
C:\Simple\core>gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-func
tions -nostdinc -fno-builtin -I./include -c -o core.o core.c
C:\Simple\core>gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-func
tions -nostdinc -fno-builtin -I./include -c -o system.o system.c
The system cannot execute the specified program.
C:\Simple\core>ld -T link.ld -o core.bin start.o core.o system.o consoleio.o
c:/djgpp/bin/ld.exe: system.o: No such file: No such file or directory (ENOENT)
C:\Simple\core>echo Done!
Done!
C:\Simple\core>concat.py
Traceback (most recent call last):
File "C:\Simple\core\concat.py", line 12, in <module>
with open("core.bin", "rb") as core:
IOError: [Errno 2] No such file or directory: 'core.bin'
Now, the interesting thing is the gcc command, which is the issue I'm having. (The other issues seem to be cascading from this.) When compiling core.c, the GCC command works just fine and great, and produces a .o file as expected. When attempting to compile system.c or consoleio.c, GCC fails, but in a very unexpected way: it appears as though windows cannot run the program. This makes zero sense to me. I've tried any number of things, including running these commands myself outside the window. Something about core.c is just special, and I can't figure out what the difference is. I literally copied that line and changed the filenames to create the other two lines that are failing.
So, in short, HELP. I'm using DJGPP and GCC on windows XP, along with a python script at the end that should tie everything together. (This all worked when the project was a single source file, but attempting to split the file into separate files has caused this strange error.)
Thanks.
PS: Yes, we are using a batch file, and I know that makes some of you cringe. However, I'd really like to understand this error before moving on to a makefile if possible. ^_^
EDIT: The accepted answer was indeed our problem, although the issue was with DJGPP, not Windows. (Windows doesn't seem to have a command limit.) The solution was to compile with MinGW instead of DJGPP, which fixed the issue right away. Thanks guys!
The line that works is 126 characters long, the others are 130 and 136 characters long. The problem is that there is a 127-character limit. I'm not sure how to get around this, but maybe make would get around it for you?...
Add -v to the gcc command line. gcc is in fact a driver, which runs several other auxiliary programs (tradicionally, the preprocessor, compiler, and assembler); -v makes it show their command lines as they are being executed, and also enables verbose mode. With this, you can see where it is failing.
As mentioned, DJGPP make (or Bash) or even a simple response file would solve this problem, so it's a non-issue. DJGPP is still plenty good as long for what it does. (P.S. Also see the ELF port or Japheth's HX mod.)