What Do I Need to Debug Pthreads

C Programming: Debugging with pthreads

Valgrind is an excellent tool to find race conditions and pthreads API misuses. It keeps a model of program memory (and perhaps of shared resources) accesses and will detect missing locks even when the bug is benign (which of course means that it will completely unexpectedly become less benign at some later point).

To use it, you invoke valgrind --tool=helgrind, here is its manual. Also, there is valgrind --tool=drd (manual). Helgrind and DRD use different models so they detect overlapping but possibly different set of bugs. False positives also may occur.

Anyway, valgrind has saved countless hours of debugging (not all of them though :) for me.

What do I need to debug pthreads?

This:

dlopen failed on 'libthread_db.so.1' - /lib/libthread_db.so.1: undefined symbol: ps_lgetfpregs
GDB will not be able to debug pthreads.

means that the libthread_db.so.1 library was not able to find the symbol ps_lgetfpregs in gdb.

Why?

Because I built gdb using Crosstoolg-NG with the "Build a static native gdb" option and this adds the -static option to gcc.

The native gdb is built with the -rdynamic option and this populates the .dynsym symbol table in the ELF file with all symbols, even unused ones. libread_db uses this symbol table to find ps_lgetfpregs from gdb.

But -static strips the .dynsym table from the ELF file.

At this point there are two options:

  1. Don't build a static native gdb if you want to debug threads.
  2. Build a static gdb and a static libthread_db (not tested)

Edit:

By the way, this does not explain why Breakpad in unable to debug multithreaded applications on my target.

How can I use console output to debug pthread interaction with JNI?

To ensure your output is flushed as soon as you send it, either turn off buffering on System.out or use System.err. On the native side, use stderr (unbuffered) instead of stdout. You can also use System.out.flush() in Java and fflush(stdout) in C to force output of any buffered data.

Note that you still might get some unexpected results, since Java and C don't use the same buffers for output streams, and there's nothing preventing the two outputs from intermixing on their way to the terminal. In practice, though, you'll likely see the output as soon as you flush it (or as soon as it's output if unbuffered).

As for when your thread actually runs, it'll be sometime after you create it. Unless you put in some explicit synchronization, it may not run until long after your Java method has returned. It's up to the system to start the new thread (outside of Java), so any number of factors might delay the thread's start, including system load, memory swapping, etc.



Related Topics



Leave a reply



Submit