Is there a way to find out what preprocessors are defined in your linux driver/kernel code when building? I could use a text search tool (I actually did), but I inherit a big tree of linux driver/kernel code. It's so big that my text search tool gets an error when I search for a certain preprocessor in the whole code tree.
gcc can dump all defined macros to stdout in preprocessing mode:
gcc -E -dM foo.c
This includes any macros predefined by the compiler, which can be a little annoying. In any case, you should be able to hack up your Makefile to contain a target that dumps this information to files for each compilation unit.
Related
Is it possible to obtain a list of preprocessor #define'd symbols in VC++? I know GCC has similar options to dump all effective #define symbols for the supplied .cpp/.h source files, but I am not sure if VC++ support this?
I am using a Mozilla open source project in Windows. There are a lots of irrelevant #define for the UNIX build env causing the source code very unreadable. I want to eliminate the irrelevant #define from the source code. The project uses Mozilla specific build scripts (automake, configure, Makefile, python scripts, and etc) to supply the symbol definitions to the compiler dynamically. Also each source file add its own #define at different #ifdef branches making manually pre-determining the complete list of symbols for a specific build impractical.
Check out Macros and Constants list in the View => Class View menu.
I'm trying to learn more about library versioning in Linux and how to put it all to work. Here's the context:
-- I have two versions of a dynamic library which expose the same set of interfaces, say libsome1.so and libsome2.so.
-- An application is linked against libsome1.so.
-- This application uses libdl.so to dynamically load another module, say libmagic.so.
-- Now libmagic.so is linked against libsome2.so. Obviously, without using linker scripts to hide symbols in libmagic.so, at run-time all calls to interfaces in libsome2.so are resolved to libsome1.so. This can be confirmed by checking the value returned by libVersion() against the value of the macro LIB_VERSION.
-- So I try next to compile and link libmagic.so with a linker script which hides all symbols except 3 which are defined in libmagic.so and are exported by it. This works... Or at least libVersion() and LIB_VERSION values match (and it reports version 2 not 1).
-- However, when some data structures are serialized to disk, I noticed some corruption. In the application's directory if I delete libsome1.so and create a soft link in its place to point to libsome2.so, everything works as expected and the same corruption does not happen.
I can't help but think that this may be caused due to some conflict in the run-time linker's resolution of symbols. I've tried many things, like trying to link libsome2.so so that all symbols are alised to symbol##VER_2 (which I am still confused about because the command nm -CD libsome2.so still lists symbols as symbol and not symbol##VER_2)... Nothing seems to work!!! Help!!!!!!
Edit: I should have mentioned it earlier, but the app in question is Firefox, and libsome1.so is libsqlite3.so shipped with it. I don't quite have the option of recompiling them. Also, using version scripts to hide symbols seems to be the only solution right now. So what really happens when symbols are hidden? Do they become 'local' to the SO? Does rtld have no knowledge of their existence? What happens when an exported function refers to a hidden symbol?
Try compiling both libsome1.so and libsome2.so to add symbol versioning, each with their own version (use the --version-script option to ld). Then link the application and libmagic.so using the new libraries. Then, libsome1.so and libsome2.so should be completely separate.
Problems can still occur if there are unversioned references to symbols. Such references can be satisfied by versioned definitions (so that it is possible to add symbol versioning to a library without breaking binary compatibility). If there are multiple symbols of the same name, it can sometimes be hard to predict which one will be used.
Regarding tools, nm -D does not display any information about symbol versioning. Try objdump -T or readelf -s instead.
I'm trying to learn more about library versioning in Linux and how to put it all to work. Here's the context:
-- I have two versions of a dynamic library which expose the same set of interfaces, say libsome1.so and libsome2.so.
-- An application is linked against libsome1.so.
-- This application uses libdl.so to dynamically load another module, say libmagic.so.
-- Now libmagic.so is linked against libsome2.so. Obviously, without using linker scripts to hide symbols in libmagic.so, at run-time all calls to interfaces in libsome2.so are resolved to libsome1.so. This can be confirmed by checking the value returned by libVersion() against the value of the macro LIB_VERSION.
-- So I try next to compile and link libmagic.so with a linker script which hides all symbols except 3 which are defined in libmagic.so and are exported by it. This works... Or at least libVersion() and LIB_VERSION values match (and it reports version 2 not 1).
-- However, when some data structures are serialized to disk, I noticed some corruption. In the application's directory if I delete libsome1.so and create a soft link in its place to point to libsome2.so, everything works as expected and the same corruption does not happen.
I can't help but think that this may be caused due to some conflict in the run-time linker's resolution of symbols. I've tried many things, like trying to link libsome2.so so that all symbols are alised to symbol##VER_2 (which I am still confused about because the command nm -CD libsome2.so still lists symbols as symbol and not symbol##VER_2)... Nothing seems to work!!! Help!!!!!!
Edit: I should have mentioned it earlier, but the app in question is Firefox, and libsome1.so is libsqlite3.so shipped with it. I don't quite have the option of recompiling them. Also, using version scripts to hide symbols seems to be the only solution right now. So what really happens when symbols are hidden? Do they become 'local' to the SO? Does rtld have no knowledge of their existence? What happens when an exported function refers to a hidden symbol?
Try compiling both libsome1.so and libsome2.so to add symbol versioning, each with their own version (use the --version-script option to ld). Then link the application and libmagic.so using the new libraries. Then, libsome1.so and libsome2.so should be completely separate.
Problems can still occur if there are unversioned references to symbols. Such references can be satisfied by versioned definitions (so that it is possible to add symbol versioning to a library without breaking binary compatibility). If there are multiple symbols of the same name, it can sometimes be hard to predict which one will be used.
Regarding tools, nm -D does not display any information about symbol versioning. Try objdump -T or readelf -s instead.
You can point a single symbol file to gdb with command the:
symbol-file /usr/lib/debug/symbolfile.so
But how to tell gdb to load all symbol-files from given path including subdirectories?
On a Linux system, you should never have to use symbol-file GDB command in the first place.
The trick is to prepare your binaries in such a way that GDB will find the symbol file automatically. This is surprisingly easy to do. Detailed instructions are here.
Use following command:
set solib-search-path path
The solution is to add-symbol-file. For instance, if symbol file is called lib.out:
add-symbol-file lib.out 0
This is particularly useful on embedded system where application developers use a library stored in ROM. The debugger needs the symbol file to reconstruct the stack if execution stops in the middle of a library function call.
This works even if the library was generated on a separate system to which the developers have no access.
Is it possible to run GDB with a program assembled with as and linked with ld? With gcc adding the flag -g allows for debugging but I get the error No symbol table is loaded. Use the "file" command when I try to add breakpoints to a loaded program.
Thanks!
EDIT Maybe I should make it clear that I'm learning and programming in assembly. All I really want is a stack trace but being able to use GDB would be great.
Resolution Running as -g does the trick.
Thank you to all that answered!!
It is possible. However, you need symbols in order to add symbolic breakpoints, and symbols are provided by debugging info; make sure your assembler and linker are providing those. EDIT With GNU as, use as -g. Or just use gcc -g: if you give it a .s file, it will invoke the assembler and linker as appropriate.
GDB understands debugging info in several formats: stabs, COFF, PE, DWARF, SOM. (Some of these are executable formats with debugging sections, others are debug info formats that can be embedded into executables, such as ELF.) gcc -g usually chooses whatever the platform's default is, gcc -ggdb usually chooses the most expressive (depending on your versions, possibly DWARF-3).
If you have debugging info embedded into or linked to by the executable, gdb will try to load it automatically. If you have it elsewhere, you may need to use file to tell gdb where to find it.
You can still debug without symbolic information. For example, you can issue break *0x89abcdef to insert a breakpoint at that address, if there's any code there.
you could try running as with the --gdwarf-2 or -g options, and make sure ld is not called with --strip-debug, and that your makefile/install process is not stripping the executable.
That's not an error preventing debugging, that's an error setting breakpoints in the way you are trying to do it. Since GDB doesn't have any symbol information, you'll have to set the breakpoints some other way.
If you don't have a symbol table, then you can't set breakpoints symbolically (by function name, line of code, etc). You could still set a breakpoint for a specific address, if you know the address you are trying to stop at.
gdb> b 0x12345678
Of course that's only useful if you know that you want to stop at 0x12345678
What does file say about your executable?