I have seen that eclipse provides a feature to load an existing executable in order to debug it, so I was following the guidelines described in here to do so. I have to say that I didn't compile the binary in eclipse, I was using my own makes files though.
However, although I can import my binary I cannot set breakpoints into the libraries( shared or not) which the binary has, as is stated in the last point of the guideline, and I don't know exactly the reason. Instead of having the content of the library, I get nothing, even if I click on the associated plus icon to the lib, see figures below
At the beginning I thought it was due to the fact that my binary didn't have the debugging flags enabled, but i checked the binary with the commands below, getting an expected output, which means that debugging flags are enables, aren't they?
readelf --debug-dump=decodedline AudioControlApp
objdump --debugging AudioControlApp
Then, I was wondering, why cannot I set the breakpoints on those libraries? Does my binary miss some compilation option?
thanks in advance,
Regards
Related
I have java application which is calling c/cpp code (it is .so files) using JNI.
I am using API's from this .so files. I have to debug .so files, how to debug it?
I tried below things:
I attached gdb to xyz.so and add breakpoints.
run java code
but not able to hit breakpoint.
can you suggest how to debug it.
after breakpoint, I can not run r or c (continue).
so how can we debug in such case?
thanks in advance.
When you compile something, as output, you have assembly code (which is run by the computer) and the symbols (which are the association between your source code and the assembly code).
In order to debug the C/C++ part, you must have the appropriate symbols in order to be able to place a break point with the same user experience you have in java. Otherwise, you'll just see a huge sequence of numbers and what you are doing is actually reverse engineering the code.
Therefore, you need the symbols which are not shipped by default (you should ask the vendor if they can provide them).
If I have a C++ source file, gcc can give all its dependencies, in a tree structure, using the -H option. But given only the C++ executable, is it possible to find all libraries and header files that went into its compilation and linking?
If you've compiled the executable with debugging symbols, then yes, you can use the symbols to get the files.
If you have .pdb files (Visual studio creates them to store sebugging information separately) you can use all kinds of programs to open them and see the source files and methods.
You can even open it with a text editor and you'll see, among the gibrish, a list of the functions and source files.
If you're using linux (or GNU compilers in general), you can use gdb (again only if you have debug symbols enables in compilation time).
Run gdb on your executable, then run the command: info sources
That's an important reason why you should always remove that flag when going into production. You don't want clients to mess around with your sources, functions, and code.
You cannot do that, because that executable might have been build on a machine on which the header files (or the C++ code, or the libraries) are private or even generated. Also, if a static library is linked in, you have no reliable way to find out.
In practice however, on Linux, using nm or objdump or ldd on the executable will often (but not always) gives you a good clue about the needed libraries.
Also, some executables are dynamically loading a plugin e.g. using dlopen, so your question might not have any sense (since that plugin is known only at runtime).
Notice also that you might not know if an executable is obtained by compiling some C++ code (you might not be able to tell if it was obtained from C, C++, D, or Ocaml, ... source code, or a mixture of them).
On Linux, if you build an executable with static linking and stripping, people won't be able to easily guess the source programming language that you have used.
BTW, on Linux distributions, it is the role of the package management system to deal with such dependencies.
As answered by Yochai Timmer if the executable contains debug information (e.g. in DWARF format) you should be able to get a lot more information.
When I try to build the source with debug mode the stack shown is totally diffrent and in case of release there are only a few methods shown in the backtrace with gdb ,
Why does this happen ? Is this because in debug mode there are extra methods , How can have two methods have the same address in debug and release mode .
Also in that case How can I build to to have accurate address information with complete stack trace . Any help would be appreciated since I am new to debugging on Linux , Windows it was much easier it seems with pdb files .
As discussed in the comments to #rockoder's answer, besides lacking debug symbols (which would be included with -g) in an optimized build whole function calls may not be present any more due to inlining.
When I try to build the source with debug mode the stack shown is
totally diffrent and in case of release there are only a few methods
shown in the backtrace with gdb , Why does this happen ? Is this
because in debug mode there are extra methods?
It is probably just due to compiler optimizations. What you call release build is probably built with compiler speed optimizations enabled and debug symbols disabled. Speed optimizations include code inlining which just copies function code in place instead of calling it, so function is not visible in call stack.
There could also be some extra/different methods, if the code was written with some appropriate preprocessor checks.
How can have two methods have the same address in debug and release
mode .
Depends on what your debug and release mode are. If they use same compiler optimizations and differ only in debug information, methods will have same addresses. If you debug build is not optimized (-O0 on GCC) then methods will be larger, as much unnecessary work is done, for example variables are read from memory before every manipulation and written back after it. Since each method will probably be smaller, functions will have different addresses, as they are generally packed one after another.
Also in that case How can I build to to have accurate address
information with complete stack trace .
Enable debug information. On GCC that would be -g3 (or -g or similar). This adds enough information for code address <-> source line queries (either from debugger or crash stack dump).
Any help would be appreciated since I am new to debugging on Linux ,
Windows it was much easier it seems with pdb files .
Are there any significant differences with Windows binaries debugging?
g++/gcc has many options used for debugging a program but the most common one is -g. Refer link. The first option discussed is -g.
Some additional information here.
Example:
Compile code without -g:
g++ broken.cpp -o broken_release
Compile code with -g:
g++ -g broken.cpp -o broken_debug
Now fire ls -l and note the size different between the files broken_release and broken_debug. Size of broken_debug should be greater then that of broken_release. That's because it contains debug information which could be used by debuggers like gdb.
I have some huge libraries that are compiled with debug info; when linking them with some small object files I write, it still takes quite a lot of time and the generated executable contains a lot of debug information of the libraries.
So is there an option to tell gcc/clang to discard those debug information inside the library? Will it improve the link speed?
If there is no easy way, should I strip the libraries? I don't think I have the priviledge since the libraries are also used by my partners who need to use the library code for debugging purpose.
As already said in the comments, there's two ways out:
Keep a local copy of said libraries, stripped of debug info.
Link with -Wl,-s or -s, which makes the linker output a stripped executable.
I am a beginner in GDB and I got it working correctly. However, I am wondering how this is used in big projects. I have a project where build is done using makefile and g++. For GDB to work, we need to compile with debug symbols on, right (g++ -g files)?
Question
Do I need to create a new target in makefile something like "debug", so that I can make a debug build like make debug. Is this the best practice?
Suppose, I need to debug only foo.cpp and is it possible to generate debug symbols only for that other than building whole program including main?
Any thoughts?
Not needed, although you may want to consider always building with -g (sometimes, you may even need to try and debug optimized (-O1, -O2, etc) code; why not leave -g on? For releases, you can always just run strip on the binary.
Yes. Build just that file with -g .
I don't think there is a big difference between the usage of gdb in big, medium or small projects. However, for big projects you must consider the amount of space required for the build, because the debugging info increases the size of the object and executable files.
If you initially underestimate the need for debugging of the whole solution you will likely suffer from your decision in the future. It is always good when the build could be done with or without debugging information, so write your build scripts carefully.
Yes, but consider my previous answer. Sometimes the problem could be coming from a module for which you don't have debugging info.
In big projects here where I work we always build with most verbose debugging info possible (like, '-ggdb3' for native gdb format or '-gdwarf-2 -g3' for access to macros in gdb).
When we're done with debugging, we just use 'strip' command to strip all debugging info from the binaries.
gcc -ggdb3 blah.c -o blah
strip blah
gdb will work without the symbols; it's just that the output is much less useful then.
It's a matter of preference. I build everything by default in debug mode, and do make release when necessary.
Yes.
You can always have the debug version's saved somewhere, and if you ever need to re-bind the symbol info, after your debugging the stripped/release version, you can just go "file /path" and gdb will re-read the symbols for that target. Also you can use "symbol-file /path" to configure symbol information to be bound to a stripped file.