How can I detect file accesses in Linux? - c++

I have a bunch of flows and data processing applications that I occasionally need to spy on, meaning I need to know what files they read. This is mostly to aid in packaging testcases, but can also be useful when debugging.
Is there a way to run the executables in such a way that produces such a list?
I have two thoughts on this:
There is a command that I can invoke and that command invokes my apps. Something along the lines of GDB. I call GDB, give it a path to the executable and some arguments and GDB calls it for me. Perhaps there's something similar to telling me how system resources are used.
Maybe the more interesting (but unnecessary side path) solution.
create library called libc.so which implements fopen (and some others)
change LD_LIBRARY_PATH to point at the new library
make a copy of the real libc.so and rename fopen (nepof, perhaps) in an editor
my library loads the copy and calls the renamed function as necessary to provide fopen functionality.
call the app which then calls my proxy fopen.
Alternative #1 would certainly be the preferable one but comments on how to do #2 more easily are welcome too.

One option is to use strace:
strace -o logfile -eopen yourapp
This will log all file-open events, but it will impose a performance penalty that may be significant. It has the advantage of being easy to use however.
Another option is to use LD_PRELOAD. This corresponds to your option #2. The basic idea is to do something like this:
#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>
int open(const char *fn, int flags) {
static int (*real_open)(const char *fn, int flags);
if (!real_open) {
real_open = dlsym(RTLD_NEXT, "open");
}
fprintf(stderr, "opened file '%s'\n", fn);
return real_open(fn, flags);
}
Then build with:
gcc -fPIC -shared -ldl -o preload-example.so preload-example.c
And run your program with eg:
$ LD_PRELOAD=$PWD/preload-example.so cat /dev/null
opened file '/dev/null'
This has much less overhead.
Note, however, that there are other entry points for opening files - eg, fopen(), openat(), or one of the many legacy compatibility entry points:
00000000000747d0 g DF .text 000000000000071c GLIBC_2.2.5 _IO_file_fopen
0000000000068850 g DF .text 000000000000000a GLIBC_2.2.5 fopen
000000000006fe60 g DF .text 00000000000000e2 GLIBC_2.4 open_wmemstream
00000000001209c0 w DF .text 00000000000000ec GLIBC_2.2.5 posix_openpt
0000000000069e50 g DF .text 00000000000003fb GLIBC_2.2.5 _IO_proc_open
00000000000dcf70 g DF .text 0000000000000021 GLIBC_2.7 __open64_2
0000000000068a10 g DF .text 00000000000000f5 GLIBC_2.2.5 fopencookie
000000000006a250 g DF .text 000000000000009b GLIBC_2.2.5 popen
00000000000d7b10 w DF .text 0000000000000080 GLIBC_2.2.5 __open64
0000000000068850 g DF .text 000000000000000a GLIBC_2.2.5 _IO_fopen
00000000000d7e70 w DF .text 0000000000000020 GLIBC_2.7 __openat64_2
00000000000e1ef0 g DF .text 000000000000005b GLIBC_2.2.5 openlog
00000000000d7b10 w DF .text 0000000000000080 GLIBC_2.2.5 open64
0000000000370c10 g DO .bss 0000000000000008 GLIBC_PRIVATE _dl_open_hook
0000000000031680 g DF .text 0000000000000240 GLIBC_2.2.5 catopen
000000000006a250 g DF .text 000000000000009b GLIBC_2.2.5 _IO_popen
0000000000071af0 g DF .text 000000000000026a GLIBC_2.2.5 freopen64
00000000000723a0 g DF .text 0000000000000183 GLIBC_2.2.5 fmemopen
00000000000a44f0 w DF .text 0000000000000088 GLIBC_2.4 fdopendir
00000000000d7e70 g DF .text 0000000000000020 GLIBC_2.7 __openat_2
00000000000a3d00 w DF .text 0000000000000095 GLIBC_2.2.5 opendir
00000000000dcf40 g DF .text 0000000000000021 GLIBC_2.7 __open_2
00000000000d7b10 w DF .text 0000000000000080 GLIBC_2.2.5 __open
0000000000074370 g DF .text 00000000000000d7 GLIBC_2.2.5 _IO_file_open
0000000000070b40 g DF .text 00000000000000d2 GLIBC_2.2.5 open_memstream
0000000000070450 g DF .text 0000000000000272 GLIBC_2.2.5 freopen
00000000000318c0 g DF .text 00000000000008c4 GLIBC_PRIVATE __open_catalog
00000000000d7b10 w DF .text 0000000000000080 GLIBC_2.2.5 open
0000000000067e80 g DF .text 0000000000000332 GLIBC_2.2.5 fdopen
000000000001e9b0 g DF .text 00000000000003f5 GLIBC_2.2.5 iconv_open
00000000000daca0 g DF .text 000000000000067b GLIBC_2.2.5 fts_open
00000000000d7d60 w DF .text 0000000000000109 GLIBC_2.4 openat
0000000000068850 w DF .text 000000000000000a GLIBC_2.2.5 fopen64
00000000000d7d60 w DF .text 0000000000000109 GLIBC_2.4 openat64
00000000000d6490 g DF .text 00000000000000b6 GLIBC_2.2.5 posix_spawn_file_actions_addopen
0000000000121b80 g DF .text 000000000000008a GLIBC_PRIVATE __libc_dlopen_mode
0000000000067e80 g DF .text 0000000000000332 GLIBC_2.2.5 _IO_fdopen
You may need to hook all of these for completeness - at the very least, the ones not prefixed with _ should be hooked. In particular, be sure to hook fopen seperately, as the libc-internal call from fopen() to open() is not hooked by a LD_PRELOAD library.
A similar caveat applies to strace - there is the 'openat' syscall as well, and depending on your architecture there may be other legacy syscalls as well. But not as many as with LD_PRELOAD hooks, so if you don't mind the performance hit, it may be an easier option.

man strace
example (assume 2343 is the process id):
# logging part
strace -p 2343 -ff -o strace_log.txt
# displaying part
grep ^open strace_log.txt

What I use is something like:
strace -o file.txt ./command
You can then
cat file.txt | grep open
to get a list of all the files that the program opened.

Related

How to find the function memory map in ARM ELF file?

I am trying to perform loop bound analysis for ARMV7m code using Z3 for a big Framework.
I would like to find the memory address that are used by a certain function inside .elf file
for example in a function foo() I have the below basic block
ldr r1, [r3, #0x20]
strb r2, [r3, #6] {__elf_header}
str r2, [r3, #0x24] {__elf_header}
str r2, [r3, #0x20] {__elf_header}
mov r3, r1
cmp r1, #0
bne #0x89f6
How can I get the initial memory location used by this function [r3, #0x20] ? Are there memory segements for every function to access or is it random ?
Given that the above basic block is a loop. Is there a way to know the memory address that will be used during its execution ?
Does the compiler for example save a memory location address from 0x20 to 0x1234 to be only accessed during the execution of such basic block ? In another word, Is there a map between a function and the range of memory address used by it ?
It is confusing as to what you are asking. First off why would any linker put the effort into randomizing things? Perhaps there is one to intentionally make the output not repeatable. But a linker is just a program and normally will do things like process the items on the command line in order, and then process each object from beginning to end...not random.
So far the rest of this seems pretty straight forward just use the tools. Your comment implies gnu tools? Since this is in part tool specific you should have tagged it as such as you cannot really make generalizations across all toolchains ever created.
unsigned int one ( void )
{
return(1);
}
unsigned int two ( void )
{
return(2);
}
unsigned int three ( void )
{
return(3);
}
arm-none-eabi-gcc -O2 -c so.c -o so.o
arm-none-eabi-objdump -d so.o
so.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <one>:
0: e3a00001 mov r0, #1
4: e12fff1e bx lr
00000008 <two>:
8: e3a00002 mov r0, #2
c: e12fff1e bx lr
00000010 <three>:
10: e3a00003 mov r0, #3
14: e12fff1e bx lr
as shown they are all in .text, simple enough.
arm-none-eabi-gcc -O2 -c -ffunction-sections so.c -o so.o
arm-none-eabi-objdump -d so.o
so.o: file format elf32-littlearm
Disassembly of section .text.one:
00000000 <one>:
0: e3a00001 mov r0, #1
4: e12fff1e bx lr
Disassembly of section .text.two:
00000000 <two>:
0: e3a00002 mov r0, #2
4: e12fff1e bx lr
Disassembly of section .text.three:
00000000 <three>:
0: e3a00003 mov r0, #3
4: e12fff1e bx lr
and now each function has its own section name.
So the rest relies heavily on linking and there is no one linker script, you the programmer choose directly or indirectly and how the final binary (elf) is built is a direct result of that choice.
If you have something like this
.text : { *(.text*) } > rom
and nothing else with respect to these functions then all of them will land in this definition, but the linker script or instructions to the linker can indicate something else causing one or more to land in its own space.
arm-none-eabi-ld -Ttext=0x1000 so.o -o so.elf
arm-none-eabi-ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000
arm-none-eabi-objdump -d so.elf
so.elf: file format elf32-littlearm
Disassembly of section .text:
00001000 <one>:
1000: e3a00001 mov r0, #1
1004: e12fff1e bx lr
00001008 <two>:
1008: e3a00002 mov r0, #2
100c: e12fff1e bx lr
00001010 <three>:
1010: e3a00003 mov r0, #3
1014: e12fff1e bx lr
and then of course
arm-none-eabi-nm -a so.elf
00000000 n .ARM.attributes
00011018 T __bss_end__
00011018 T _bss_end__
00011018 T __bss_start
00011018 T __bss_start__
00000000 n .comment
00011018 T __data_start
00011018 T _edata
00011018 T _end
00011018 T __end__
00011018 ? .noinit
00001000 T one <----
00000000 a so.c
00080000 T _stack
U _start
00001000 t .text
00001010 T three <----
00001008 T two <----
which is simply because there is a symbol table in the file
Symbol table '.symtab' contains 22 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00001000 0 SECTION LOCAL DEFAULT 1
2: 00000000 0 SECTION LOCAL DEFAULT 2
3: 00000000 0 SECTION LOCAL DEFAULT 3
4: 00011018 0 SECTION LOCAL DEFAULT 4
5: 00000000 0 FILE LOCAL DEFAULT ABS so.c
6: 00001000 0 NOTYPE LOCAL DEFAULT 1 $a
7: 00001008 0 NOTYPE LOCAL DEFAULT 1 $a
8: 00001010 0 NOTYPE LOCAL DEFAULT 1 $a
9: 00001008 8 FUNC GLOBAL DEFAULT 1 two
10: 00011018 0 NOTYPE GLOBAL DEFAULT 1 _bss_end__
11: 00011018 0 NOTYPE GLOBAL DEFAULT 1 __bss_start__
12: 00011018 0 NOTYPE GLOBAL DEFAULT 1 __bss_end__
13: 00000000 0 NOTYPE GLOBAL DEFAULT UND _start
14: 00011018 0 NOTYPE GLOBAL DEFAULT 1 __bss_start
15: 00011018 0 NOTYPE GLOBAL DEFAULT 1 __end__
16: 00001000 8 FUNC GLOBAL DEFAULT 1 one
17: 00011018 0 NOTYPE GLOBAL DEFAULT 1 _edata
18: 00011018 0 NOTYPE GLOBAL DEFAULT 1 _end
19: 00080000 0 NOTYPE GLOBAL DEFAULT 1 _stack
20: 00001010 8 FUNC GLOBAL DEFAULT 1 three
21: 00011018 0 NOTYPE GLOBAL DEFAULT 1 __data_start
but if
arm-none-eabi-strip so.elf
arm-none-eabi-nm -a so.elf
arm-none-eabi-nm: so.elf: no symbols
arm-none-eabi-objdump -d so.elf
so.elf: file format elf32-littlearm
Disassembly of section .text:
00001000 <.text>:
1000: e3a00001 mov r0, #1
1004: e12fff1e bx lr
1008: e3a00002 mov r0, #2
100c: e12fff1e bx lr
1010: e3a00003 mov r0, #3
1014: e12fff1e bx lr
The elf file format is somewhat trivial you can easily write code to parse it, you do not need a library or anything like that. And with simple experiments like these can easily understand how these tools work.
How can I get the initial memory used by this function ?
Assuming you mean the initial address assuming not relocated. You just read it out of the file. Simple.
Are there memory segments for every function to access or is it random ?
As demonstrated above, the command line option you mention later in a comment (should have been in the question, you should edit the question for completeness) does exactly that makes a custom section name per function. (what happens if you have the same non-global function name in two or more objects? you can easily figure this out on your own)
Nothing is random here, you would need to have a reason to randomize things for security or other, it is more often preferred that a tool outputs the same or at least similar results each time with the same inputs (some tools will embed a build date/time in the file and that may vary from one build to the next).
If you are not using gnu tools then binutils may still be very useful with parsing and displaying elf files anyway.
arm-none-eabi-nm so.elf
00011018 T __bss_end__
00011018 T _bss_end__
00011018 T __bss_start
00011018 T __bss_start__
00011018 T __data_start
00011018 T _edata
00011018 T _end
00011018 T __end__
00001000 T one
00080000 T _stack
U _start
00001010 T three
00001008 T two
nm so.elf (x86 binutils not arm)
00001000 t $a
00001008 t $a
00001010 t $a
00011018 T __bss_end__
00011018 T _bss_end__
00011018 T __bss_start
00011018 T __bss_start__
00011018 T __data_start
00011018 T _edata
00011018 T _end
00011018 T __end__
00001000 T one
00080000 T _stack
U _start
00001010 T three
00001008 T two
Or can build with clang and examine with gnu, etc. Obviously disassembly won't work, but some tools will.
If this is not what you were asking then you need to re-write your question or edit it so we can understand what you are actually asking.
Edit
I would like to know if there is a map between a function and the range of memory address used by it ?
In general no. The term function implies but is not limited to high level languages like C, etc. Where the machine code clearly has no clue nor should it and well optimized code does not necessarily have a single exit point from the function, much less a return marking the end. For architectures like the various arm instruction sets the return instruction is not the end of the "function", there is pool data that may follow.
But let's look at what gcc does.
unsigned int one ( unsigned int x )
{
return(x+1);
}
unsigned int two ( void )
{
return(one(2));
}
unsigned int three ( void )
{
return(3);
}
arm-none-eabi-gcc -O2 -S so.c
cat so.s
.cpu arm7tdmi
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 1
.eabi_attribute 30, 2
.eabi_attribute 34, 0
.eabi_attribute 18, 4
.file "so.c"
.text
.align 2
.global one
.arch armv4t
.syntax unified
.arm
.fpu softvfp
.type one, %function
one:
# Function supports interworking.
# args = 0, pretend = 0, frame = 0
# frame_needed = 0, uses_anonymous_args = 0
# link register save eliminated.
add r0, r0, #1
bx lr
.size one, .-one
.align 2
.global two
.syntax unified
.arm
.fpu softvfp
.type two, %function
two:
# Function supports interworking.
# args = 0, pretend = 0, frame = 0
# frame_needed = 0, uses_anonymous_args = 0
# link register save eliminated.
mov r0, #3
bx lr
.size two, .-two
.align 2
.global three
.syntax unified
.arm
.fpu softvfp
.type three, %function
three:
# Function supports interworking.
# args = 0, pretend = 0, frame = 0
# frame_needed = 0, uses_anonymous_args = 0
# link register save eliminated.
mov r0, #3
bx lr
.size three, .-three
.ident "GCC: (GNU) 10.2.0"
we see this is being placed in the file, but what does it do?
.size three, .-three
One reference says this is used so that the linker can remove the function if it is not used. And I have seen that feature in play so good to know (you could have looked this up just as easily as I did)
So in that context the info is there and you can extract it (lesson for the reader).
And then if you use this gcc compiler option that you mentioned
-ffunction-sections
Disassembly of section .text.one:
00000000 <one>:
0: e2800001 add r0, r0, #1
4: e12fff1e bx lr
Disassembly of section .text.two:
00000000 <two>:
0: e3a00003 mov r0, #3
4: e12fff1e bx lr
Disassembly of section .text.three:
00000000 <three>:
0: e3a00003 mov r0, #3
4: e12fff1e bx lr
[ 4] .text.one
PROGBITS 00000000 000034 000008 00 0 0 4
[00000006]: ALLOC, EXEC
[ 5] .rel.text.one
REL 00000000 0001a4 000008 08 12 4 4
[00000040]: INFO LINK
[ 6] .text.two
PROGBITS 00000000 00003c 000008 00 0 0 4
[00000006]: ALLOC, EXEC
[ 7] .rel.text.two
REL 00000000 0001ac 000008 08 12 6 4
[00000040]: INFO LINK
[ 8] .text.three
PROGBITS 00000000 000044 000008 00 0 0 4
[00000006]: ALLOC, EXEC
[ 9] .rel.text.three
REL 00000000 0001b4 000008 08 12 8 4
[00000040]: INFO LINK
That is giving us a size of the sections.
In general with respect to software compiled or in particular assembled, assume that a function doesn't have boundaries. As you can see above the one function is inlined into the two function, invisibly, so how big is an inlined function within another function? How many instances of a function are there in a binary? Which one do you want to monitor and know the size of, performance of, etc? Gnu has this feature with gcc, you can see if it is there with other languages or tools. Assume the answer is no, and then if you happen to find a way, then that is good.
Does the compiler saves a memory segment to be only accessed by a certain function ?
I have no idea what this means. The compiler doesn't make memory segments the linker does. How the binary is put into a memory image is a linker thing not a compiler thing for starters. Segments are just a way to communicate between tools that these bytes are for starters code (read only ideally), initialized data, or uninitialized data. Perhaps extending to read only data and then make up your own types.
If your ultimate goal is to find the bytes that represent the high level concept of "function" in memory (assuming no relocation, etc) by looking at the elf binary using the gnu toolchain. That is possible in theory.
The first thing we appear to know is that the OBJECT contains this information so that a linker feature can remove unused functions for size. But that does not automatically mean that the output binary from the linker also includes this information. You need to find where this .size lands in the object and then look for that in the final binary.
The compiler turns one language into another, often from a higher level to a lower level but not always depends on the compiler and input/output languages. C to assembly or C to machine code or what about Verilog to C++ for a simulation is that higher or lower? The terms .text, .data, .bss are not part of the language but more of a habit based on learned experience and helps as mentioned communicate with the linker so that the output binaries can be more controlled for various targets. Normally as shown above the compiler, gcc in this case, since no generalities can be made in this area across all tools and languages or even all C or C++ tools all the code for all the functions in the source file land in one .text segment by default. You have to do extra work to get something different. So the compiler in general does not make a "segment" or "memory segment" for each...In general. You already solved your problem it seems by using a command line option that turns every function into its own segment and now you have a lot more control over size and location, etc.
Just use the file format and/or the tools. This question or series of questions boils down into just go look at the elf file format. This is not a Stack Overflow question as questions seeking recommendations for external information is not for this site.
Does the compiler for example save a memory location address from 0x20 to 0x1234 to be only accessed during the execution of such basic block ? In another word, Is there a map between a function and the range of memory address used by it ?
"save"? the compiler does not link the linker links. Is that memory "only" accessed during the execution of that block? Well in a pure textbook theory yes, but in reality branch prediction and prefetch or cache line fills can also access that "memory".
Unless doing self-modifying code or using the mmu in interesting ways you do not re-use an address space for more than one function within an application. In general. So function foo() is implemented somewhere and bar() somewhere else. Hand written asm from the good old days you might have foo() branch right into the middle of bar() to save space, get better performance or to make the code harder to reverse engineer or whatever. But compilers are not that efficient, they do their best to turn concepts like functions into first off functional(ly equivalent to the high level code) and then second, if desired smaller or faster or both relative to a straight brute force conversion between languages. So barring inlining and tail (leaf?, I call it tail) optimizations and such, one could say there are some number of bytes at some address that define a compiled function. But due to the nature of processor technology you cannot assume those bytes are only accessed by the processor/chip/system busses only when executing that function.

g++ says it can't load a library that exists

I have a case where g++ refuses to load a library. I have a file deps/lib/libskgxp11.so. I place -L deps/lib and -lskgxp11 on the g++ command. I get the following error:
error while loading shared libraries: libskgxp11.so: cannot open shared object file: No such file or directory
My overall purpose is to get a test to run with gtest that connects to Oracle, executes select * from dual, and compares the result.
I have the following in Makefile:
g++ -m32 -o $(test_target) -L deps/lib -Wl,--start-group $(dep_libs) -lpthread -ldl -lskgxpr -lskgxp11 -locrb11 -locr11 -lhasgen11 -lnnz11 -lskgxn2 -locrutl11 -lclntsh $(test_objects) -Wl,--end-group
I have used the same basic sequence of -Wl,--start group, all dependent static libraries, all dependent shared libaries, all object files, -Wl,--end-group on other projects and it works just fine.
Notice the -m32, we're doing everything in 32 bits right now. All the other shared libraries load fine, and are all in the same dir:
ls deps/lib/libskgxpr.so deps/lib/libskgxp11.so deps/lib/libocrb11.so deps/lib/libocr11.so deps/lib/libhasgen11.so deps/lib/libnnz11.so deps/lib/libskgxn2.so deps/lib/libocrutl11.so deps/lib/libclntsh.so | cat
deps/lib/libclntsh.so
deps/lib/libhasgen11.so
deps/lib/libnnz11.so
deps/lib/libocr11.so
deps/lib/libocrb11.so
deps/lib/libocrutl11.so
deps/lib/libskgxn2.so
deps/lib/libskgxp11.so
deps/lib/libskgxpr.so
I do notice one strange thing, it seems that the following group of libraries are somehow related:
deps/lib/libskgxp11.so
deps/lib/libskgxpcompat.so
deps/lib/libskgxpd.so
deps/lib/libskgxpg.so
deps/lib/libskgxpr.so
They each seem to define the same functions. The other 4 seem to depend on libskgxp11, in the sense that if I link any of the other 4 by themselves with a -l option, g++ complains that it can't load libskgxp11.
I have a command sequence that can tell me for each remaining function I need to get from some shared lib, which shared lib(s) contain it. It gives the following:
skgxpcdel
deps/lib/libskgxp11.so
deps/lib/libskgxpcompat.so
deps/lib/libskgxpd.so
deps/lib/libskgxpg.so
deps/lib/libskgxpr.so
skgxpcini_with_stats
deps/lib/libskgxp11.so
deps/lib/libskgxpcompat.so
deps/lib/libskgxpd.so
deps/lib/libskgxpg.so
deps/lib/libskgxpr.so
skgxpcon_with_stats
deps/lib/libskgxp11.so
deps/lib/libskgxpcompat.so
deps/lib/libskgxpd.so
deps/lib/libskgxpg.so
deps/lib/libskgxpr.so
...
where skgxpcdel is a func I'm looking for. All of the outstanding functions I need give the same list of the same 5 libraries.
If I run objdump -T on the 5 libraries, they all seem to be 32-bit shared libs, I don't see anything special about the one that doesn't load compared to the ones that do:
for i in deps/lib/libskgxp11.so deps/lib/libskgxpcompat.so deps/lib/libskgxpd.so deps/lib/libskgxpg.so deps/lib/libskgxpr.so; do objdump -T $i | head; done
deps/lib/libskgxp11.so: file format elf32-i386
DYNAMIC SYMBOL TABLE:
0000380c l d .init 00000000 .init
00003b90 l d .text 00000000 .text
00008cc4 l d text.unlikely 00000000 text.unlikely
000a719c l d .fini 00000000 .fini
000a71c0 l d .rodata 00000000 .rodata
000bbe80 l d .eh_frame 00000000 .eh_frame
deps/lib/libskgxpcompat.so: file format elf32-i386
DYNAMIC SYMBOL TABLE:
00000ca0 l d .init 00000000 .init
00000d18 l d .text 00000000 .text
00000e04 l d text.unlikely 00000000 text.unlikely
00001618 l d .fini 00000000 .fini
00001640 l d .rodata 00000000 .rodata
0000188c l d .eh_frame 00000000 .eh_frame
deps/lib/libskgxpd.so: file format elf32-i386
DYNAMIC SYMBOL TABLE:
00000ca0 l d .init 00000000 .init
00000d18 l d .text 00000000 .text
00000e04 l d text.unlikely 00000000 text.unlikely
00001618 l d .fini 00000000 .fini
00001640 l d .rodata 00000000 .rodata
0000188c l d .eh_frame 00000000 .eh_frame
deps/lib/libskgxpg.so: file format elf32-i386
DYNAMIC SYMBOL TABLE:
0000380c l d .init 00000000 .init
00003b90 l d .text 00000000 .text
00008cc4 l d text.unlikely 00000000 text.unlikely
000a719c l d .fini 00000000 .fini
000a71c0 l d .rodata 00000000 .rodata
000bbe80 l d .eh_frame 00000000 .eh_frame
deps/lib/libskgxpr.so: file format elf32-i386
DYNAMIC SYMBOL TABLE:
0000380c l d .init 00000000 .init
00003b90 l d .text 00000000 .text
00008cc4 l d text.unlikely 00000000 text.unlikely
000a719c l d .fini 00000000 .fini
000a71c0 l d .rodata 00000000 .rodata
000bbe80 l d .eh_frame 00000000 .eh_frame
I'm scratching my head wondering why I can't link the libskgxp11.so, and what is the relationship between this group of 5 libs.
Any help would be greatly appreciated.
For reference, here are some command sequences I ran to get the list of problem functions and track down the libs:
# Get what project needs
make run-tests 2>&1 | grep -Po '(?<=undefined reference to ).*' | tr -d "\`'" | sort -u > undefined.txt
# Complete content of undefined.txt
skgxpcdel
skgxpcini_with_stats
skgxpcon_with_stats
skgxpdis
skgxpdmpctx
skgxpdmpobj
skgxp_get_epid
skgxpgettabledef
skgxpmmap
skgxpnetmappush
skgxppost
skgxprqhi
skgxpsz
skgxptrace
skgxpunmap
skgxpveri
skgxpvrpc
skgxpwait
# Get what deps provide, for comparison to what project needs
(for i in deps/lib/*.so;do objdump -TC $i | grep -E '^...............F';done) | grep -v '[*]UND[*]' | awk '{print $NF}' | sort -u > have.txt
# First few lines of have.txt
_A_BSafeError
AddCRLBerToList
add_error_table
afidrv
AHChooseRandomConstructor2
AHSecretCBCConstructor2
AHSecretCBCPadConstructor2
AI_AES_CBC
# See what is common between what project needs and what deps provide
comm -12 have.txt undefined.txt > left.txt
# A diff of undefined.txt and left.txt indicates they are identical
# Get what deps provide, in a way searchable by a person
(for i in deps/lib/*.so;do echo "====$i"; objdump -TC $i | grep -E '^...............F';done) | grep -v '[*]UND[*]' | awk '{print $NF}' > have-files.txt
# Here's a sample of first two shared libs and some of their funcs, from have-files.txt
====deps/lib/libagfw11.so
clsagfw_get_check_type
clsagfw_exit
clsagfw_get_attrvalue
====deps/lib/libagtsh.so
naecsn
lmsapbn
kokogtv
# for each func left, try to find lib that contains it
(for i in `cat left.txt`;do echo $i; for j in deps/lib/*.so;do (objdump -TC $j | grep -E '^...............F' | grep -v '[*]UND[*]' | grep -q $i) && echo " $j"; done; done) 2>&1 | more
# Output for first two missing funcs:
skgxpcdel
deps/lib/libskgxp11.so
deps/lib/libskgxpcompat.so
deps/lib/libskgxpd.so
deps/lib/libskgxpg.so
deps/lib/libskgxpr.so
skgxpcini_with_stats
deps/lib/libskgxp11.so
deps/lib/libskgxpcompat.so
deps/lib/libskgxpd.so
deps/lib/libskgxpg.so
deps/lib/libskgxpr.so
As helpfully suggested in the comments, the problem was occurring trying to run the program. I just needed to use the env command to set LD_LIBRARY_PATH to include the deps/lib dir where all the shared libs are stored:
run-tests: $(test_target)
env "LD_LIBRARY_PATH=deps/lib:$$LD_LIBRARY_PATH" $(test_target)
Thanks.

GDB can't find source file

I am trying to debug into OpenCV code but gdb fails to load the OpenCV source file.
Checking for the source file existence:
$ls -l /home/rui/DriveSo/opencv/modules/core/src/matrix.cpp
-rw-r--r-- 1 rui rui 156046 May 11 21:46 /home/rui/DriveSo/opencv/modules/core/src/matrix.cpp
After linking with OpenCV Debug mode libraries I start dbg and add this to the list of source directories:
$gdb DriveSo
GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1
....
Reading symbols from DriveSo...done.
(gdb) directory /home/rui/DriveSo/opencv/modules/core/src
Source directories searched: /home/rui/DriveSo/opencv/modules/core/src:$cdir:$cwd
(gdb) break matrix.cpp:2349
No source file named matrix.cpp.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (matrix.cpp:2349) pending.
Even after starting the session gdb still does not find the source file:
(gdb) start
Temporary breakpoint 2 at 0x41d2cf: file ../../DriveSo.dkt/main.cpp, line 11.
Starting program: /home/rui/DriveSo/repositories/trunk/builds/build-DriveSo-Desktop_Qt_5_5_0_GCC_64bit-Debug/DriveSo
....
Temporary breakpoint 2, main (argc=1, argv=0x7fffffffe5a8) at ../../DriveSo.dkt/main.cpp:11
11 QCoreApplication::setApplicationName(QString("DriveSo"));
(gdb)
What can be causing this (to me) unexpected behavior?
Following up on the suggestion by iksajotien, as far as I see the executable has debug information...
$ objdump --syms DriveSo | grep debug
0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges
0000000000000000 l d .debug_info 0000000000000000 .debug_info
0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev
0000000000000000 l d .debug_line 0000000000000000 .debug_line
0000000000000000 l d .debug_str 0000000000000000 .debug_str
0000000000000000 l d .debug_ranges 0000000000000000 .debug_ranges
...and the shared libraries opened by it...
$ lsof -p 12159
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
...
DriveSo 12159 rui mem REG 8,6 20289800 26740265 /usr/local/lib/libopencv_core.so.3.1.0
...
... also have debug information.
$ objdump --syms /usr/local/lib/libopencv_core.so.3.1.0 | grep debug
0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges
0000000000000000 l d .debug_info 0000000000000000 .debug_info
0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev
0000000000000000 l d .debug_line 0000000000000000 .debug_line
0000000000000000 l d .debug_str 0000000000000000 .debug_str
0000000000000000 l d .debug_ranges 0000000000000000 .debug_ranges
gdb info shared:
$gdb DriveSo
GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1
...
Reading symbols from DriveSo...done.
(gdb) run
Starting program: /home/rui/DriveSo/repositories/trunk/builds/build-DriveSo-Desktop_Qt_5_5_0_GCC_64bit-Debug/DriveSo
...
^C
Program received signal SIGINT, Interrupt.
...
(gdb) info shared
From To Syms Read Shared Object Library
0x00007ffff7ddcae0 0x00007ffff7df5130 Yes /lib64/ld-linux-x86-64.so.2
No linux-vdso.so.1
0x00007ffff7158860 0x00007ffff794a910 Yes /usr/local/lib/libopencv_core.so.3.1
0x00007ffff6e5d880 0x00007ffff6e63a0b Yes /usr/local/lib/libopencv_highgui.so.3.1
0x00007ffff5493840 0x00007ffff690ce00 Yes /usr/local/lib/libopencv_imgproc.so.3.1
0x00007ffff50aa6f0 0x00007ffff5158bd1 Yes /usr/local/lib/libopencv_features2d.so.3.1
0x00007ffff4db8640 0x00007ffff4e3de75 Yes /usr/local/lib/libopencv_imgcodecs.so.3.1
0x00007ffff4b72a80 0x00007ffff4b931b0 Yes /usr/local/lib/libopencv_videoio.so.3.1
0x00007ffff47b7d40 0x00007ffff4920f80 Yes /usr/local/lib/libopencv_calib3d.so.3.1
...
---Type <return> to continue, or q <return> to quit---
Looking at gdb source code solib.c has the following at line 1053:
if (! ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ()))
&& so->symbols_loaded
&& !objfile_has_symbols (so->objfile))
{
so_missing_debug_info = 1;
ui_out_field_string (uiout, "syms-read", "Yes (*)");
}
else
ui_out_field_string (uiout, "syms-read",
so->symbols_loaded ? "Yes" : "No");
I therefore assume symbols are loaded and debug info exists otherwise libraries would be listed with Yes (*) or No
I faced the exact same issue and fixed it by appending an rpath to my makefile.
g++ -o $# $< -L$(LIBS) -lmylib -Wl,-rpath,$(LIBS)

Listing library functions in GCC

Is is possible to list all the library functions available in any library/headers in GCC command line?
Anything similar to program like JAVAP which is available for Java?
Thanks.
You can use objdump to list symbols in a shared libraries (or executables):
$objdump -T /usr/lib/libclang.so
<...snipped...>
0000000000124150 g DF .text 00000000000000c1 Base clang_reparseTranslationUnit
000000000010fe40 g DF .text 0000000000000021 Base clang_getNullRange
0000000000135760 g DF .text 000000000000009f Base clang_getPointeeType
0000000000124290 g DF .text 0000000000000289 Base clang_parseTranslationUnit
000000000012b790 g DF .text 0000000000000935 Base clang_findReferencesInFile
0000000000110b80 g DF .text 000000000000001c Base clang_getRangeEnd
0000000000127d20 g DF .text 0000000000000022 Base clang_disposeCodeCompleteResults
0000000000135e10 g DF .text 0000000000000037 Base clang_isPODType
000000000010f870 g DF .text 0000000000000025 Base clang_getTranslationUnitCursor
0000000000129b50 g DF .text 00000000000002c1 Base clang_getDiagnosticOption
As you can see it lists the different symbols and their relative address.

What does notype() and notype mean when seeing the C++ library information using dumpbin? [duplicate]

I used dumpbin /symbols to see the library I created. Some functions have UNDEF notype in the output. What does that mean? Is there any link to study the structure of dumpbin output?
We can take a look at the MSDN documentation for dumpbin /SYMBOLS:
This option displays the COFF symbol table. Symbol tables exist in all
object files. A COFF symbol table appears in an image file only if it
is linked with /DEBUG.
The following is a description of the output for /SYMBOLS. Additional
information on the meaning of /SYMBOLS output can be found by looking
in winnt.h (IMAGE_SYMBOL and IMAGE_AUX_SYMBOL), or COFF documentation.
Given the following sample dump:
Dump of file main.obj
File Type: COFF OBJECT
COFF SYMBOL TABLE
000 00000000 DEBUG notype Filename | .file
main.cpp
002 000B1FDB ABS notype Static | #comp.id
003 00000000 SECT1 notype Static | .drectve
Section length 26, #relocs 0, #linenums 0, checksum 722C964F
005 00000000 SECT2 notype Static | .text
Section length 23, #relocs 1, #linenums 0, checksum 459FF65F, selection 1 (pick no duplicates)
007 00000000 SECT2 notype () External | _main
008 00000000 UNDEF notype () External | ?MyDump##YAXXZ (void __cdecl MyDump(void))
String Table Size = 0x10 bytes
Summary
26 .drectve
23 .text
The following description, for lines that begin with a symbol number,
describes columns that have information relevant to users:
The first three-digit number is the symbol index/number.
If the third column contains SECTx, the symbol is defined in that
section of the object file. But if UNDEF appears, it is not defined in
that object and must be resolved elsewhere.
The fifth column (Static, External) tells whether the symbol is
visible only within that object, or whether it is public (visible
externally). A Static symbol, _sym, wouldn't be linked to a Public
symbol _sym; these would be two different instances of functions named
_sym.
The last column in a numbered line is the symbol name, both
decorated and undecorated.
And notype() means exactly what it says on the tin: it has no type.