Debugging shared library .so with JNI using gdb - c++

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).

Related

Finding all libraries and header files forming a C++ executable

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.

Debugging existing executable doesn't allow to set breakpoints in library files

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

Executable runtime crash caused by linking with dynamic library

Stack: MIPS, Linux, C, C++ using GNU Tools to compile and link (building on x86 for MIPS)
Fair warning: I'm a C, C++ novice, feel free to suggest anything which might be obvious as it's possible I have not tried it yet.
I am able to build an executable which dynamically links to a library (live555), if I statically link to this everything works fine, however when I attempt to dynamically link the executable crashes during runtime. To confirm I am building the .so files correctly, I've also tried building other executables (the test tools included with live555) to dynamically link against these .so libs and these tools work fine.
The linking/build seems to work fine, no errors or warnings are thrown during the build. I can inspect the crashing executable with readelf -d and clearly see the .so references. I can also run ldd on the MIPS system on the executable and the libraries seem to be loaded fine, strace output also shows these libraries as being loaded. Unfortunately the strace output doesn't really provide me with any insite, I've talked with others familiar with this system and they are not sure what the problem is.
Just looking for ideas and tools to try, if anyone has any thoughts I'd appropriate them!
Thanks for reading
There is not enough information here to start troubleshooting in depth. Some ideas to start debugging, from least to most time-consuming:
After you run ldd on your executable, check the path(s) where that library is being loaded from, make sure the library is the version you compiled / linked against. Easy way is to get it's MD5 hash on your target and host, make sure they are the same.
Also check to make sure you don't have multiple instances of the library installed
Double check the aliases for your library, make sure they point to the same place
Try enabling crash dump generation $> ulimit -c unlimited, run gdb or DDD, load the crash dump and inspect your environment.
Check your CFLAGS, it could be as #YannRamin said, you need -fPIC for MIPS. You can run make -n to see how your binary is being generated.
Check your LDPATH env on target and make sure it is sensible; empty is perfectly fine btw.
Check your LDFLAGS during compile / linking. You might have to run make -n, look for gcc command or collect command, then copy-paste the entire line and add --verbose to the end so you can see exactly what the linker is doing. You might have to fix paths for sources / object files, depending on how your build system is setup.
The idea is to try and eliminate potential issues, such as:
wrong library version: installed vs compiled against
multiple locations / bad aliasing
symbol pollution when compiling / linking
many others
You're lucky that you have Linux installed, so should be fairly easy, just might be time consuming.

how to debug a release version of library in Visual Studio

I need to debug the release version of my linked library. I am already generating debug information with my release build following this article but how can I do the same with the library project? Note that library project doesn't have link page in properties where debug information is created in the link above. I am using VS2010.
What I really want is to make TRACE work whlile debugging the library. I tried to link debug version of library with the release exe but it creates linker errors.
What I really want is to make TRACE work...
You mean the MFC TRACE macro? The one that writes messages to the debug/output window of the debugger?
Unfortunately, even if you do fix your build settings so that your final executable contains debug information for your static library it won't bring back those trace statements. TRACE is a macro and therefore is handled by the compiler preprocessor. When you compile in release mode, that macro is redefined to be a no-op. It's as if the TRACE statement was deleted from the source code.
Even if you do resolve the problem of adding debug symbols to your library and executable, it won't bring those trace statements back. They were removed during the compile phase.
So what to do? Turns out, if you dig deep enough into those macros, they are ultimately calling a Win32 function OutputDebugString. This call is available in both debug and release versions of the ms libraries. So ... you could replace the trace macros with explicit calls to OutputDebugString - it's not as convenient to code with but at least you will get your debug output in release mode.
BTW, I finally gave up on all those macros years ago and we have completely replaced them with log4cplus calls. Any logging framework would be better than the trace macros - because the time when you really need tracing is not when you are debugging but when your code is in production and you cannot reproduce the problem locally. It's much better to log to a file which the customer can send to you, then rely on tracing that only works in the debugger. Something to consider anyways...
A static library isn't linked, so it's no surprise that linker options are unavailable. You basically just need to tell the compiler to produce debugging information. From there, creating the library is little more than putting a bunch of object files together into a single file.
So basically, just tell the compiler to produce debug information, and the library will contain debug info.

Can you retrieve source from a debug-compiled binary?

I was digging around and found an executable for something I wrote in Visual C++ 6.0 about 8 years ago. I never backed up the source code, but I think I always compiled everything in debug mode. I also vaguely remember hearing somewhere that "you can't decompile an executable into source code unless you have your compiler's debugging symbols or something." The code would have sentimental value, but its not mission-critical that I retrieve it.
That's the background; here are the questions:
How do I check if an executable was compiled in debug mode or not?
If it is, what information comes with a debug mode executable?
Can I retrieve full source code? Failing that, can I get any substantial improvement when decompiling compared to a release version? If so, how?
Thanks,
-- Michael Burge
I do not believe there is a flag though you might find something by using PEDUMP which will dump out COFF file formats (Windows EXE and DLLs). You can infer if an executable was compiled for debug rather quickly by running Dependecy Walker and seeing if your EXE is linking to any debug DLLs (suffixed with D, e.g. MSVCRT5D.DLL).
FYI in VC6 Debug and Release are simple named builds, not modes per say, each build a collection of compiler and linker settings. The EXE is just code, debug exes normally not having been optimized which makes using a debugger with it easy (versus debugging optimized code). Thus you can compile a Release binary with Debug Symbols which is sometimes useful for tracking down optimized code errors.
Debug EXEs and DLLs did not contain any debugging information but instead had a sidecar PDB file that resided in the same folder and contains all the debugging symbols information that was produced during compilation.
No, source is source and not compiled into the symbols file or executables. There are some amazing decompilers out there that can regenerate decent C versions of your code but they are amazing only in how good the C is, not in how well they can recreate your source.
With Visual Studio, I am afraid you can't, since the debug executable doesn't contain the source. Visual Studio generates pdb files that only contains the mapping between the binary and the sources filenames and line numbers, but you still need the source code with them. That might be different with gcc, which I think integrate the source itself inside the binaries.
I think that many disassemblers can show the source if a binary is compiled in debug mode. For example, I use OllyDBG and it has an option to show the source, although I've never tried.