I always use gdb in Linux and it works ok, this is my first time use gdb in mac which is different with Linux.
(gdb) b main
Breakpoint 1 at 0x100000ec4
(gdb) r
Starting program: /Users/vinllen/code/tmp/lhm/homework
warning: Could not open OSO archive file "/BinaryCache/corecrypto/corecrypto-233.1.2~26/Symbols/BuiltProducts/libcorecrypto_static.a"
warning: `/BinaryCache/coreTLS/coreTLS-35.20.2~10/Objects/coretls.build/coretls.build/Objects-normal/x86_64/system_coretls_vers.o': can't open to read symbols: No such file or directory.
warning: Could not open OSO archive file "/BinaryCache/coreTLS/coreTLS-35.20.2~10/Symbols/BuiltProducts/libcoretls_ciphersuites.a"
warning: Could not open OSO archive file "/BinaryCache/coreTLS/coreTLS-35.20.2~10/Symbols/BuiltProducts/libcoretls_handshake.a"
warning: Could not open OSO archive file "/BinaryCache/coreTLS/coreTLS-35.20.2~10/Symbols/BuiltProducts/libcoretls_record.a"
warning: Could not open OSO archive file "/BinaryCache/coreTLS/coreTLS-35.20.2~10/Symbols/BuiltProducts/libcoretls_stream_parser.a"
Breakpoint 1, 0x0000000100000ec4 in main ()
(gdb) l
No symbol table is loaded. Use the "file" command.
(gdb) n
Single stepping until exit from function main,
which has no line number information.
It looks like command l and n cannot be execute correctly, what's the problem ?
Here is my Makefile:
objects = main.o conversion.o slitemlist.o uims.o testdrivers.o
homework:$(objects)
g++ -o homework $(objects)
conversion.o: conversion.h base.h
slitemlist.o: slitemlist.h base.h
uims.o: conversion.h base.h conversion.h slitemlist.h
testdrivers.o: testdrivers.h
.PHONY: clean
clean:
rm homework $(objects)
Here is my Makefile:
You will not have a good time debugging this program on Linux either: you've compiled it without debug symbols (the -g flag).
Your real question is not "how do I use GDB on MacOS", but rather "how do I write Makefile such that I can debug".
You should add a lines like this to your Makefile:
CFLAGS = -g
CXFLAGS = -g # if building C++
Related
I'm trying to get gdb working with C++ programs on Ubuntu 20.04. What I need is to be able to set a breakpoint (for example, break main.cpp:3 gdb command) and then run until the breakpoint, but at the moment both start and run fail because they "Cannot insert breakpoint" and "Cannot access memory". For me gdb fails even with very simple examples. This is main.cpp content:
#include <iostream>
int main() {
std::cout << "Hello World!";
return 0;
}
I found somewhere that using -no-pie might help to get gdb working (with breakpoints), so I compile the program by running g++ -ggdb3 -no-pie -o main main.cpp (I also tried -g instead of -ggdb3, and -fno-PIE in addition to -no-pie). When I try to use gdb, it complains "Cannot insert breakpoint 1":
gdb -q main
Reading symbols from main...
(gdb) start
Temporary breakpoint 1 at 0x1189: file main.cpp, line 3.
Starting program: /tmp/main
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x1189
Without -no-pie result is the same. Only thing that changes with or without -no-pie is the hexadecimal address, without -no-pie it is low like 0x1189 (as shown above), with -no-pie it can be 0x401176, but everything else exactly the same, I keep getting the "Cannot access memory at address" warning in both cases.
If I use starti instead of start, it works at first, but after a few nexti iterations it prints usual message "Cannot insteart breakpoint":
gdb -q main
Reading symbols from main...
(gdb) starti
Starting program: /tmp/main
Program stopped.
0x00007ffff7fd0100 in ?? () from /lib64/ld-linux-x86-64.so.2
(gdb) nexti
0x00007ffff7fd0103 in ?? () from /lib64/ld-linux-x86-64.so.2
...
(gdb) nexti
Warning:
Cannot insert breakpoint 0.
Cannot access memory at address 0x4
0x00007ffff7fd0119 in ?? () from /lib64/ld-linux-x86-64.so.2
(gdb) nexti
0x00007ffff7fd011c in ?? () from /lib64/ld-linux-x86-64.so.2
...
(gdb) nexti
Warning:
Cannot insert breakpoint 0.
Cannot access memory at address 0x1c
0x000055555556ca22 in ?? ()
(gdb) nexti
[Detaching after fork from child process 3829827]
...
[Detaching after fork from child process 3829840]
Hello World![Inferior 1 (process 3819010) exited normally]
So I can use nexti, but cannot use next and obviously cannot insert breakpoints.
I tried -Wl,-no-pie (by running g++ -Wl,-no-pie -ggdb3 -o main main.cpp; adding -no-pie does not change anything) but this option causes a strange linker error:
/usr/bin/ld: cannot find -lgcc_s
/usr/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
When I google the error, I only found advice to try -no-pie instead of -Wl,-no-pie, and no other solutions. Since debugging C++ programs is very common activity, I feel like I'm missing something obvious but I found no solution so far.
To make it easier to understand what exact commands I use and to make it clear I'm not mixing up directories and to show what versions of g++ and gdb I'm using, here is full terminal log:
$ ls
main.cpp
$ g++ --version | grep Ubuntu
g++ (Ubuntu 9.3.0-10ubuntu2) 9.3.0
$ g++ -ggdb3 -no-pie -o main main.cpp
$ ls
main main.cpp
$ gdb --version | grep Ubuntu
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
$ readelf -h main | grep 'Type: .*EXEC'
Type: EXEC (Executable file)
$ gdb -q main
Reading symbols from main...
(gdb) start
Temporary breakpoint 1 at 0x401176: file main.cpp, line 3.
Starting program: /tmp/main/main
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x401176
For completeness, I tried the same without -no-pie:
$ rm main
$ g++ -ggdb3 -o main main.cpp
$ readelf -h main | grep 'Type: .*'
Type: DYN (Shared object file)
$ gdb -q main
Reading symbols from main...
(gdb) start
Temporary breakpoint 1 at 0x1189: file main.cpp, line 3.
Starting program: /tmp/main/main
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x1189
As you can see the only difference with or without -no-pie is the memory address, but the issue and warnings are the same. Without -no-pie this may be expected, but I do not understand why this is happening if I compiled with -no-pie and what else I can try to solve the issue.
This:
g++ -ggdb3 -no-pie -o main main.cpp
should produce a non-PIE executable. You should be able to verify that it non-PIE by looking at readelf -h main | grep 'Type: .*EXEC' (PIE binaries have ET_DYN type).
This:
Temporary breakpoint 1 at 0x1189: file main.cpp, line 3.
is unambiguously a PIE binary (a non-PIE binary will not have any code below 0x40000 on x86_64 Linux).
Conclusion: you are either debugging the wrong binary (e.g. you are compiling main in a different directory from the one in which you are debugging), or you are not telling is the whole story.
I want to debug with stander library in gdb.
I ran gdb with argument -d to specify the source file of standard libary.
$ gdb ./test -d /usr/src/glibc/glibc-2.27/
test.cpp:
#include<iostream>
#include<string>
using namespace std;
int main(){
string hex("0x0010");
long hex_number = strtol(hex.c_str(), NULL, 16);
cout << hex_number << endl;
return 0;
}
However, gdb told me it can not find source file strtol.c.
(gdb) b 8
Breakpoint 1 at 0xc8c: file /home/purin/Desktop/CodeWork/adv_unix_programming/hw1/test.cpp, line 8.
(gdb) run
Starting program: /home/purin/Desktop/CodeWork/adv_unix_programming/hw1/test
Breakpoint 1, main () at /home/purin/Desktop/CodeWork/adv_unix_programming/hw1/test.cpp:8
8 long hex_number = strtol(hex.c_str(), NULL, 16);
(gdb) s
__strtol (nptr=0x7fffffffd820 "0x0010", endptr=0x0, base=16) at ../stdlib/strtol.c:106
106 ../stdlib/strtol.c: file or directory does not exits
(gdb) info source
Current source file is ../stdlib/strtol.c
Compilation directory is /build/glibc-OTsEL5/glibc-2.27/stdlib
Source language is c.
Producer is GNU C11 7.3.0 -mtune=generic -march=x86-64 -g -O2 -O3 -std=gnu11 -fgnu89-inline -fmerge-all-constants -frounding-math -fstack-protector-strong -fPIC -ftls-model=initial-exec -fstack-protector-strong.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.
Since gdb can find source code if I execute this command:
(gdb) dir /usr/src/glibc/glibc-2.27/stdlib/
I am sure that I have strtol.c in path /usr/src/glibc/glibc-2.27/stdlib/strtol.c and the library has debug information.
Why gdb cannot search the directories under /usr/src/glibc/glibc-2.27/ to find out stdlib/strtol.c?
Maybe the reason is that if you join two paths /usr/src/glibc/glibc-2.27/ and ../stdlib/strtol.c you get the path /usr/src/glibc/stdlib/strtol.c, but not the expected path /usr/src/glibc/glibc-2.27/stdlib/strtol.c. The reason why ../stdlib/strtol.c is stored in the debug info, very likely is a build directory /build/glibc-OTsEL5/glibc-2.27/build used, and ../stdlib/strtol.c is the relative path to the build directory.
One of solutions is run
$ gdb ./test -d /usr/src/glibc/glibc-2.27/stdlib/
I have bunch of source code which I compiled using -ggdb3 flag.
I have copied the source code and executable to an another machine.
When I run the exe in gdb it does not show the statements at the line numbers when it breaks.
This is what I see
Breakpoint 1, TestCode (handler=0x806e110, args=0xffffd2b0)
at ../myfile.c:1080
1080 ../myfile.c: No such file or directory.
(gdb) n
1083 in ../myfile.c
(gdb)
1084 in ../myfile.c
(gdb)
1085 in ../myfile.c
I even tried setting the dir path using gdb dir command by giving the name of the topmost directory of the source code but no help.
Example my source code directory structure is like
C
|
--------------
| |
D E
|
F
|
-----------
| |
S T
The file I am debugging may be in some inner folder say F.
While I gave the path of folder C in gdb dir
dir /home/C
Any way to resolve this issue?
More details are:
> OS SUSE Linux Enterprise Server 11 (x86_64)
> gcc version 4.3.4 [gcc-4_3-branch revision 152973] (SUSE Linux)
> GNU gdb (GDB) SUSE (7.5.1-0.7.29)
Here are the Makefile details
#
# Makefile for building demo code on SUSE Linux
all : SLIBINSTALLDIR = $(SDESTDIR)$(SLIBDIR)
###########################################
# Defines #
###########################################
CC = --mode=compile gcc
LINK =$(DESTDIR)libtool --mode=link gcc
INDEPSDIR = ../../../../../dependencies/internal
MODULE = TestCode
INCLUDE = -I../ -I$(INDEPSDIR)/include
CFLAGS := $(CFLAGS) $(INCLUDE) -DN_PLAT_UNIX -DN_PLAT_GNU -DVERSION=0x00010002 -D_GNU_SOURCE -g -ggdb3
CSRC = ../myfile.c ../decode.c ../encode.c
COBJ = $(CSRC:.c=.o)
COBJ1 = $(CSRC:.c=.lo)
TestCode:$(COBJ)
$(LINK) $(CFLAGS) -o TestCode $(COBJ1) -all-static
DESRC = ../main.c
DEOBJ = $(DESRC:.c=.o)
You should define a source path substitution rule using command:
set substitute-path from to
It will substitute from part into to allowing to find sources in new location.
See https://sourceware.org/gdb/onlinedocs/gdb/Source-Path.html.
Also info sources command will be useful to remember from part in the command above in case you forgot where your sources were located before copying.
Small portion of the Makefile
CC=gcc -g -MMD
EXE=MegaCli
all:$(EXE)
LDFLAGS=-02
SOUCE_DIR=$(UNIV_VIVA_CLI)lib/linux/
LINK=g++
Ctm.o: $(SOURCE_DIR)Ctm.cpp
$(CC) $(CCFLAGS) $(SOURCE_DIR)Ctm.cpp
Before someone else have logged the same post. But my Makefile is same as the answer given to that post. But still I am getting error No Debugging Symbol found. Then I tried the below command too.
(gdb) exec - file MegaCli
error>No symbol table is loaded use the file command
Please give some solution to the above.
It's not clear how you are invoking GDB. Don't do this:
gdb
(gdb) exec - file MegaCli # I am not sure what this even means!
Do this:
gdb MegaCli
(gdb) run
I have one binary and one shared library.
The shared library is compiled with:
all:
g++ -g -shared -fpic $(SOURCES) -o libmisc.so
the binary is compiled with:
LIBS=-L../../misc/src
LDFLAGS=-lmisc
all:
g++ -g -o mainx $(INCLUDE) $(SOURCE) $(LIBS) $(LDFLAGS)
I set in ~/.bashrc
export LD_LIBRARY_PATH=/mnt/sda5/Programming/misc/src/
to the libmisc.so output path.
Debugging from console works fine:
gdb mainx
However from Emacs22, launching gdb fails with the following message:
Starting program: /mnt/sda5/Programming/main/src/mainx
/mnt/sda5/Programming/main/src/mainx: error while loading shared libraries: libmisc.so: cannot open shared object file: No such file or directory
This looks very tricky for the moment, and I couldn't solve it. I am not sure if this a emacs's problem, or I should pass a parameter in gdb's command line.
Emacs probably does not read your .bashrc before it invokes gdb. Try to put 'set solib-search-path' and 'set solib-absolute-path in your .gdbinit file instead
Emacs doesn't invoke gdb via bash, but rather invokes it directly, and so .bashrc changes do not take effect and LD_LIBRARY_PATH is not set.
If you quit emacs, open a new shell (so LD_LIBRARY_PATH is set), start emacs in it, and then do M-X gdb, then it would work.
Setting solib-search-path in GDB is a hack.
A much better fix is to build the executable in such a way that it doesn't need LD_LIBRARY_PATH to begin with:
LDFLAGS=-lmisc -Wl,-rpath=/mnt/sda5/Programming/misc/src
Another way is to create a .gdbinit file in your $HOME and set the LD_LIBRARY_PATH there:
# file .gdbinit
set env LD_LIBRARY_PATH=/mnt/sda5/Programming/misc/src/
This is convenient if you need to debug with that LD_LIBRARY_PATH frequently (and don't want to remember running emacs from your shell every time).