I have the code as follows:
// global.cpp
int a = 5;
register unsigned b __asm("r9");
int test()
{
b = 4;
a++;
b = b + 7;
int c = a + b;
return c;
}
I run clang -target arm -c global.cpp -emit-llvm -o global.bc & llc -march=arm -filetype=asm global.bc -o -, but I get the following error:
.text
.syntax unified
.eabi_attribute 67, "2.09" # Tag_conformance
.eabi_attribute 6, 1 # Tag_CPU_arch
.eabi_attribute 8, 1 # Tag_ARM_ISA_use
.eabi_attribute 34, 1 # Tag_CPU_unaligned_access
.eabi_attribute 17, 1 # Tag_ABI_PCS_GOT_use
.eabi_attribute 20, 1 # Tag_ABI_FP_denormal
.eabi_attribute 21, 1 # Tag_ABI_FP_exceptions
.eabi_attribute 23, 3 # Tag_ABI_FP_number_model
.eabi_attribute 24, 1 # Tag_ABI_align_needed
.eabi_attribute 25, 1 # Tag_ABI_align_preserved
.eabi_attribute 38, 1 # Tag_ABI_FP_16bit_format
.eabi_attribute 18, 4 # Tag_ABI_PCS_wchar_t
.eabi_attribute 26, 2 # Tag_ABI_enum_size
.eabi_attribute 14, 0 # Tag_ABI_PCS_R9_use
.file "global.cpp"
LLVM ERROR: Invalid register name "r9".
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace.
Stack dump:
0. Program arguments: llc -march=arm -filetype=asm global.bc -o -
1. Running pass 'Function Pass Manager' on module 'global.bc'.
2. Running pass 'ARM Instruction Selection' on function '#_Z4testv'
#0 0x00007f345d2fea1a llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0xb12a1a)
#1 0x00007f345d2fc7a4 llvm::sys::RunSignalHandlers() (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0xb107a4)
#2 0x00007f345d2fc8f8 (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0xb108f8)
#3 0x00007f345c39fde0 (/lib64/libc.so.6+0x38de0)
#4 0x00007f345c39fd61 raise (/lib64/libc.so.6+0x38d61)
#5 0x00007f345c389536 abort (/lib64/libc.so.6+0x22536)
#6 0x00007f345d2165e6 llvm::report_fatal_error(llvm::Twine const&, bool) (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0xa2a5e6)
#7 0x00007f345f40b269 (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0x2c1f269)
#8 0x00007f345dbb9000 llvm::SelectionDAGISel::Select_READ_REGISTER(llvm::SDNode*) (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0x13cd000)
#9 0x00007f345dbbc52b llvm::SelectionDAGISel::SelectCodeCommon(llvm::SDNode*, unsigned char const*, unsigned int) (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0x13d052b)
#10 0x00007f345f3fcf21 (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0x2c10f21)
#11 0x00007f345dbb85e8 llvm::SelectionDAGISel::DoInstructionSelection() (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0x13cc5e8)
#12 0x00007f345dbc11b5 llvm::SelectionDAGISel::CodeGenAndEmitDAG() (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0x13d51b5)
#13 0x00007f345dbc4560 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0x13d8560)
#14 0x00007f345dbc7501 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0x13db501)
#15 0x00007f345f406014 (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0x2c1a014)
#16 0x00007f345d6c949d (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0xedd49d)
#17 0x00007f345d4503f8 llvm::FPPassManager::runOnFunction(llvm::Function&) (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0xc643f8)
#18 0x00007f345d451971 llvm::FPPassManager::runOnModule(llvm::Module&) (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0xc65971)
#19 0x00007f345d44f70b llvm::legacy::PassManagerImpl::run(llvm::Module&) (/usr/lib/llvm/11/bin/../lib64/libLLVM-11.so+0xc6370b)
#20 0x000056232e849ef6 main (/usr/lib/llvm/11/bin/llc+0xeef6)
#21 0x00007f345c38ae6b __libc_start_main (/lib64/libc.so.6+0x23e6b)
#22 0x000056232e84a6ca _start (/usr/lib/llvm/11/bin/llc+0xf6ca)
Could anyone give me hints how to force global variable b to be stored in register r9 ?
My LLVM & Clang version: 11.0.0
Update:
I want to put a global variable to specific register (R9 in this example) since I am planning to port global register variables feature from ARM to my own back-end (I need global variables to be allocated in registers due to that no stack space for doing this). I just would like to confirm if this functionality can be used on ARM, so I could port this feature to my back-end.
"global variables in registers" is only supported for SP register on ARM. Patches are welcome :)
This post may not directly related to the question. But since I want to fix some global variables to corresponding registers on my own backed, I finally make it works by modifying LLVM via manipulating IR and writing the back-end. The details are as follows:
For the back-end, I refer to Tutorial: Creating an LLVM Backend for
the Cpu0 Architecture and remember to define the getRegisterByName function in XXXISelLowering.cpp.
For IR manipulation, I creating a pass to do that. Mainly, there are 3 steps:
Getting a list of global variable and its corresponding register (via cl:opt)
Iterating over each global variable:
Creating corresponding metadata (MDNode, NamedMDNode)
Initializing via module-level inline assembly (appendModuleInlineAsm)
Creating new instruction using corresponding metadata, which will be used to replace original users of global variable. Using IRBuilder might be easier to create new instruction to replace original one.
Replacing original global variable with corresponding metadata. Note that this step should be done outside the iteration since replacing might break iteration.
I also found that following references help me to learn LLVM:
Getting Started with LLVM Core Libraries
LLVM doxygen (Find the class you interested and look at what functions are provided)
Grep source code directly to learn how to use the class, functions, etc.
I would like to know the paths of all code files that went into the compilation of a whole C/C++ project with multiple resulting binaries. I know about https://github.com/rizsotto/Bear et al which you can wrap around your "make" call and which tell you the gcc/g++ calls but they of course show me only the C/C++ files which were compiled - how can I find out which of the headers were needed for the compilation and ended up in one of the resulting binaries?
GCC has the runtime option -M. From the GCC man page:
-M Instead of outputting the result of preprocessing, output a rule
suitable for make describing the dependencies of the main source
file. The preprocessor outputs one make rule containing the object
file name for that source file, a colon, and the names of all the
included files, including those coming from -include or -imacros
command-line options.
Unless specified explicitly (with -MT or -MQ), the object file name
consists of the name of the source file with any suffix replaced
with object file suffix and with any leading directory parts
removed. If there are many included files then the rule is split
into several lines using \-newline. The rule has no commands.
This option does not suppress the preprocessor's debug output, such
as -dM. To avoid mixing such debug output with the dependency
rules you should explicitly specify the dependency output file with
-MF, or use an environment variable like DEPENDENCIES_OUTPUT.
Debug output is still sent to the regular output stream as normal.
Passing -M to the driver implies -E, and suppresses warnings with
an implicit -w.
Clang supports the very same option
GCC and Clang both support the -H option (as well as the -M option and its relatives).
-H
Print the name of each header file used, in addition to other normal activities. Each name is indented to show how deep in the ‘#include’ stack it is. Precompiled header files are also printed, even if they are found to be invalid; an invalid precompiled header file is printed with ‘...x’ and a valid one with ‘...!’ .
The -H output is reported on standard error, not standard output.
The -H option gives more and different information compared with the -M option. It reports on the nesting levels (one or more leading dots), and shows each time a header is included — even if the content is ignored because of header guard macros:
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
…content of header…
#endif /* HEADER_H_INCLUDED */
This can be useful; having the formatted make dependency lines (as generated by -M) can also be useful.
Example output (from compiling one source file from one of my programs — make generated the compiler command line, of course):
$ gcc -H -g -O3 -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -DSYSTEM=MACOS_X -DSTR_SYSTEM='"(macOS Mojave 10.14.6 - Darwin 18.7.0)"' -I/Users/jonathanleffler/inc -DDEBUG -DHASH_STATISTICS -c main.c
. make.h
.. /Users/jonathanleffler/inc/posixver.h
.. config.h
.. /usr/include/assert.h
... /usr/include/sys/cdefs.h
.... /usr/include/sys/_symbol_aliasing.h
.... /usr/include/sys/_posix_availability.h
.. /usr/include/ctype.h
... /usr/include/_ctype.h
.... /usr/include/runetype.h
..... /usr/include/_types.h
...... /usr/include/sys/_types.h
....... /usr/include/machine/_types.h
........ /usr/include/i386/_types.h
....... /usr/include/sys/_pthread/_pthread_types.h
.. /usr/include/errno.h
... /usr/include/sys/errno.h
.. /usr/include/inttypes.h
... /usr/include/Availability.h
.... /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include-fixed/AvailabilityInternal.h
... /usr/include/sys/_types/_wchar_t.h
... /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include/stdint.h
.... /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include-fixed/stdint.h
..... /usr/include/sys/_types/_int8_t.h
..... /usr/include/sys/_types/_int16_t.h
..... /usr/include/sys/_types/_int32_t.h
..... /usr/include/sys/_types/_int64_t.h
..... /usr/include/_types/_uint8_t.h
..... /usr/include/_types/_uint16_t.h
..... /usr/include/_types/_uint32_t.h
..... /usr/include/_types/_uint64_t.h
..... /usr/include/sys/_types/_intptr_t.h
...... /usr/include/machine/types.h
....... /usr/include/i386/types.h
........ /usr/include/sys/_types/_u_int8_t.h
........ /usr/include/sys/_types/_u_int16_t.h
........ /usr/include/sys/_types/_u_int32_t.h
........ /usr/include/sys/_types/_u_int64_t.h
........ /usr/include/sys/_types/_intptr_t.h
........ /usr/include/sys/_types/_uintptr_t.h
..... /usr/include/_types/_intmax_t.h
..... /usr/include/_types/_uintmax_t.h
.. /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include-fixed/limits.h
... /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include-fixed/syslimits.h
.... /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include-fixed/limits.h
..... /usr/include/limits.h
...... /usr/include/machine/limits.h
....... /usr/include/i386/limits.h
........ /usr/include/i386/_limits.h
...... /usr/include/sys/syslimits.h
.. /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include/stdbool.h
.. /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include-fixed/stdio.h
... /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include/stdarg.h
... /usr/include/_stdio.h
.... /usr/include/sys/_types/_va_list.h
.... /usr/include/sys/_types/_size_t.h
.... /usr/include/sys/_types/_null.h
.... /usr/include/sys/stdio.h
... /usr/include/sys/_types/_off_t.h
... /usr/include/sys/_types/_ssize_t.h
... /usr/include/secure/_stdio.h
.... /usr/include/secure/_common.h
.. /usr/include/stdlib.h
... /usr/include/sys/wait.h
.... /usr/include/sys/_types/_pid_t.h
.... /usr/include/sys/_types/_id_t.h
.... /usr/include/sys/signal.h
..... /usr/include/sys/appleapiopts.h
..... /usr/include/machine/signal.h
...... /usr/include/i386/signal.h
..... /usr/include/machine/_mcontext.h
...... /usr/include/i386/_mcontext.h
....... /usr/include/mach/machine/_structs.h
........ /usr/include/mach/i386/_structs.h
..... /usr/include/sys/_pthread/_pthread_attr_t.h
..... /usr/include/sys/_types/_sigaltstack.h
..... /usr/include/sys/_types/_ucontext.h
...... /usr/include/machine/_mcontext.h
..... /usr/include/sys/_types/_sigset_t.h
..... /usr/include/sys/_types/_uid_t.h
.... /usr/include/sys/resource.h
..... /usr/include/sys/_types/_timeval.h
... /usr/include/sys/_types/_wchar_t.h
... /usr/include/malloc/_malloc.h
.. /usr/include/string.h
... /usr/include/secure/_string.h
.. /usr/include/sys/stat.h
... /usr/include/sys/_types/_timespec.h
... /usr/include/sys/_types/_blkcnt_t.h
... /usr/include/sys/_types/_blksize_t.h
... /usr/include/sys/_types/_dev_t.h
... /usr/include/sys/_types/_ino_t.h
... /usr/include/sys/_types/_mode_t.h
... /usr/include/sys/_types/_nlink_t.h
... /usr/include/sys/_types/_gid_t.h
... /usr/include/sys/_types/_time_t.h
... /usr/include/sys/_types/_s_ifmt.h
.. /usr/include/unistd.h
... /usr/include/sys/unistd.h
.... /usr/include/sys/_types/_posix_vdisable.h
.... /usr/include/sys/_types/_seek_set.h
... /usr/include/sys/_types/_useconds_t.h
.. /Users/jonathanleffler/inc/debug.h
... /Users/jonathanleffler/inc/kludge.h
.. /Users/jonathanleffler/inc/emalloc.h
.. list.h
.. /Users/jonathanleffler/inc/sastrings.h
.. /Users/jonathanleffler/inc/stderr.h
... /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include/stdarg.h
. /Users/jonathanleffler/inc/getopt.h
Multiple include guards may be useful for:
/opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include-fixed/syslimits.h
/usr/include/assert.h
/usr/include/errno.h
/usr/include/machine/limits.h
/usr/include/secure/_stdio.h
/usr/include/secure/_string.h
/usr/include/sys/_posix_availability.h
/usr/include/sys/_symbol_aliasing.h
/usr/include/sys/_types/_seek_set.h
$
That lists 110 headers; there are just five that are repeated:
2 /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include-fixed/limits.h
2 /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include/stdarg.h
2 /usr/include/machine/_mcontext.h
2 /usr/include/sys/_types/_intptr_t.h
2 /usr/include/sys/_types/_wchar_t.h
Other projects I work on have many more repeats. Taking one source file, more or less at random (I know it's a big file; I don't think it is the worst), there is a list of headers included 4 or more times — there are many included 2 and 3 times. The total number of header lines from -H for this file is 592. Project-specific directory and file names have been changed to protect the innocent — and the file names were massaged with realpath(2) to deal with the idiosyncratic use of ../subdir/header.h style names in the source code and in the included headers, which -H expands to names such as:
../incl/../subdir1/../subdir1/../subdir2/../subdir2/header27.h
Counts:
4 /usr/include/errno.h
4 /usr/include/time.h
4 /opt/project/incl/header1.h
4 /opt/project/incl/header2.h
4 /opt/project/subdir/header3.h
4 /opt/project/subdir/header4.h
4 /opt/project/subdir/header5.h
5 /opt/project/incl/header6.h
5 /opt/project/subdir/header7.h
6 /opt/project/subdir/header8.h
6 /opt/project/subdir/header9.h
6 /work5/gcc/v9.2.0/lib/gcc/x86_64-pc-linux-gnu/9.2.0/include-fixed/limits.h
7 /opt/project/subdir/header10.h
14 /usr/include/bits/wordsize.h
14 /opt/project/subdir/header11.h
22 /work5/gcc/v9.2.0/lib/gcc/x86_64-pc-linux-gnu/9.2.0/include/stddef.h
I'm trying to get debugging metadata from an llvm Instruction using the DILocation class.
However, when I query the DILocation for the filename where the instruction came from, I get a filename with a
directory tagged onto the front.
I though it would return just the file
and the entire directory path should be retrieved via a call to getDirectory().
For example, instead of XMain_0.c I end up with pbg/XMain_0.c
I compiled my bitcode like this:
XMain_0.o: pbg/XMain_0.c
$(CC) <snip> -c pbg/XMain_0.c
Does the fact that I passed in my source with a directory on it
mean that the metadata saves the source filename as the input?
Here's a cut down example:
const llvm::Instruction* inst //passed in
MDNode *n = inst->getMetadata("dbg");
DILocation loc(n);
file = loc.getFilename().str(); // => pbg/XMain_0.c
dir = loc.getDirectory().str(); // => /projects/pbg/pbg-m/DIR
Are there calls I can make to "normalize" this data or do I need to do it by hand?
Clang 3.1 if that matters.
I think it depends on the invocation of the compiler. If you run:
clang -c somedir/somefile.c
Then the full somedir/somefile.c will be the filename.
How does your invocation look like?
There is nothing weird about it. The debugger will look for source files relative to some project root, and if you compile files likes this, it's the way they are going to be found. gcc does the same thing:
/tmp$ pwd
/tmp
/tmp$ cat subdir/test.c
int foo() {
return 42;
}
/tmp$ gcc -g -O0 -c subdir/test.c -o test.o
/tmp$ readelf --debug-dump=info test.o | grep -A4 compile_unit
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
<c> DW_AT_producer : (indirect string, offset: 0x0): GNU C 4.6.3
<10> DW_AT_language : 1 (ANSI C)
<11> DW_AT_name : (indirect string, offset: 0xc): subdir/test.c
<15> DW_AT_comp_dir : (indirect string, offset: 0x1a): /tmp
I'm using Eclipse Juno with the CDT Plugin, but I've tried in Indigo as well and this problem happens there too. I'm on Ubuntu 12.04.
I've created a new C++ project with the following code. I've set a breakpoint on the second line.
#include <iostream>
using namespace std;
int main() {
cout << "Hello world" << endl;
cout << "Hi there" << endl; // I've set a breakpoint here using eclipse
}
And my Makefile is this
CXX := g++
CXXFLAGS := -g -c
LDFLAGS := -g -std=c++11
OBJ_FILES := main.o
.PHONY: all clean
all: $(OBJ_FILES)
$(CXX) $(LDFLAGS) $(OBJ_FILES) -o proj2
main.o: main.cpp
$(CXX) $(CXXFLAGS) main.cpp -o main.o
clean:
rm -rf *.o proj2
When I run this in Debug mode in eclipse, everything builds fine, but when it runs, gdb spits out this message:
Error in re-setting breakpoint 1: Function "/home/gulshan/Code/EECS281Workspace/Project 2/main.cpp:7" not defined.
It might be worth noting that in this case I've unchecked the option eclipse gives you to break at startup, but when that option is check, it is able to break at the first line without any problem.
What's going on? Here is the GDB trace in case that helps.
707,811 2-environment-cd "/home/gulshan/Code/EECS281Workspace/Project 2"
707,811 2^done
707,812 (gdb)
707,812 3-gdb-set breakpoint pending on
707,813 3^done
707,813 (gdb)
707,814 4-gdb-set detach-on-fork on
707,814 4^done
707,814 (gdb)
707,815 5-enable-pretty-printing
707,815 5^done
707,815 (gdb)
707,815 6-gdb-set python print-stack none
707,816 6^done
707,816 (gdb)
707,816 7-gdb-set print object on
707,817 7^done
707,817 (gdb)
707,818 8-gdb-set print sevenbit-strings on
707,818 8^done
707,818 (gdb)
707,818 9-gdb-set host-charset UTF-8
707,818 9^done
707,819 (gdb)
707,819 10-gdb-set target-charset UTF-8
707,819 10^done
707,819 (gdb)
707,820 11-gdb-set target-wide-charset UTF-32
707,820 11^done
707,820 (gdb)
707,820 12source .gdbinit
707,821 &"source .gdbinit\n"
707,821 &".gdbinit: No such file or directory.\n"
707,821 12^error,msg=".gdbinit: No such file or directory."
707,821 (gdb)
707,822 13-gdb-set target-async off
707,822 13^done
707,822 (gdb)
707,823 14-gdb-set auto-solib-add on
707,823 14^done
707,824 (gdb)
707,827 15-file-exec-and-symbols --thread-group i1 "/home/gulshan/Code/EECS281Workspace/Project 2/pr\
oj2"
707,828 15^done
707,828 (gdb)
707,834 16-break-insert --thread-group i1 -f "\"/home/gulshan/Code/EECS281Workspace/Project 2/main.c\
pp\":7"
707,836 16^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x00000000004007d4"\
,func="main()",file="main.cpp",fullname="/home/gulshan/Code/EECS281Workspace/Project 2/main.cpp",lin\
e="7",times="0",original-location="/home/gulshan/Code/EECS281Workspace/Project 2/main.cpp:7"}
707,837 (gdb)
707,843 17-inferior-tty-set --thread-group i1 /dev/pts/2
707,844 17^done
707,844 (gdb)
707,847 18-exec-run --thread-group i1
707,848 =thread-group-started,id="i1",pid="22982"
707,848 =thread-created,id="1",group-id="i1"
707,848 18^running
707,848 *running,thread-id="all"
707,848 (gdb)
707,849 19-list-thread-groups --available
707,851 =library-loaded,id="/lib64/ld-linux-x86-64.so.2",target-name="/lib64/ld-linux-x86-64.so.2",h\
ost-name="/lib64/ld-linux-x86-64.so.2",symbols-loaded="0",thread-group="i1"
707,870 &"Error in re-setting breakpoint 1: Function \"/home/gulshan/Code/EECS281Workspace/Project 2\
/main.cpp:7\" not defined.\n"
707,872 =breakpoint-modified,bkpt={number="1",type="breakpoint",disp="keep",enabled="n",addr="<PENDI\
NG>",pending="/home/gulshan/Code/EECS281Workspace/Project 2/main.cpp:7",times="0",original-location=\
"/home/gulshan/Code/EECS281Workspace/Project 2/main.cpp:7"}
707,873 =library-loaded,id="/usr/lib/x86_64-linux-gnu/libstdc++.so.6",target-name="/usr/lib/x86_64-l\
inux-gnu/libstdc++.so.6",host-name="/usr/lib/x86_64-linux-gnu/libstdc++.so.6",symbols-loaded="0",thr\
ead-group="i1"
707,874 =library-loaded,id="/lib/x86_64-linux-gnu/libc.so.6",target-name="/lib/x86_64-linux-gnu/libc\
.so.6",host-name="/lib/x86_64-linux-gnu/libc.so.6",symbols-loaded="0",thread-group="i1"
707,874 =library-loaded,id="/lib/x86_64-linux-gnu/libm.so.6",target-name="/lib/x86_64-linux-gnu/libm\
.so.6",host-name="/lib/x86_64-linux-gnu/libm.so.6",symbols-loaded="0",thread-group="i1"
707,874 =library-loaded,id="/lib/x86_64-linux-gnu/libgcc_s.so.1",target-name="/lib/x86_64-linux-gnu/\
libgcc_s.so.1",host-name="/lib/x86_64-linux-gnu/libgcc_s.so.1",symbols-loaded="0",thread-group="i1"
708,269 =thread-exited,id="1",group-id="i1"
708,270 =thread-group-exited,id="i1",exit-code="0"
708,270 *stopped,reason="exited-normally"
708,270 (gdb)
708,278 20-gdb-exit
708,278 21-data-evaluate-expression $_exitcode
708,291 19^error,msg="Quit"
708,291 (gdb)
708,292 20^exit
708,292 22-break-delete --thread-group i1 1
Looks like there's a bug in GDB 7.4 that has a problem with setting breakpoints using paths with spaces: http://sourceware.org/bugzilla/show_bug.cgi?id=13798
I've removed all of the spaces in the path containing the file and it works now.
It may happen also if you have modified the code during a debug session. Just Run/"Remove all breakpoints" solves the problem.
[root#xxx memcached-1.4.5]# objdump -R memcached-debug |grep freeaddrinfo
0000000000629e10 R_X86_64_JUMP_SLOT freeaddrinfo
...
(gdb) disas freeaddrinfo
Dump of assembler code for function freeaddrinfo:
0x00000037aa4baf10 <freeaddrinfo+0>: push %rbp
0x00000037aa4baf11 <freeaddrinfo+1>: push %rbx
0x00000037aa4baf12 <freeaddrinfo+2>: mov %rdi,%rbx
So I know freeaddrinfo is a dynamically linked function,but how to know which .so it's defined in?
See this answer. The info symbol freeadrinfo is one way to find out.
On Linux and Solaris you can also use ldd and LD_DEBUG=symbols. For example, if you wanted to find out where localtime in /bin/date is coming from:
LD_DEBUG=bindings ldd -r /bin/date 2>&1 | grep localtime
26322: binding file /bin/date [0] to /lib/libc.so.6 [0]: normal symbol `localtime' [GLIBC_2.2.5]
For certain low version gdb, "info symbol " could not work as you want.
So please use below method:
Run 'p symbol_name' to get symbol address
(gdb) p test_fun
$1 = {<text variable, no debug info>} 0x84bcc4 <test_fun>
Check /proc/PID/maps to find out the module which the symbol address is in.
# more /proc/23275/maps
007ce000-0085f000 r-xp 00000000 fd:00 3524598 /usr/lib/libtest.so
0x84bcc4 is in [007ce000, 0085f000]
Inside the libraries directory you could execute the following command to search for a specific symbol on all libraries:
for file in $(ls -1 *.so); do echo "-------> $file"; nm $file; done | c++filt | grep SYMBOL*
An enhanced version would be to list all libraries that are linked to the executable (through ldd) and go after each library listed searching if the symbol is defined there. Depending on your *nix you might have to tweak the cut parsing:
APP=firefox; for symbol in $(nm -D $APP | grep "U " | cut -b12-); do for library in $(ldd $APP | cut -d ' ' -f3- | cut -d' ' -f1); do for lib_symbol in $(nm -D $library | grep "T " | cut -b12-); do if [ $symbol == $lib_symbol ]; then echo "Found symbol: $symbol at [$library]"; fi ; done; done; done;