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:
- Don't build a static native gdb if you want to debug threads.
- 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
How to Convert Dynamically Linked Application to Statically One
Distro for Linux Kernel Development
The Sort -R Command Doesn't Sort Lines Randomly in Linux
Which Characters Are Allowed in a Bash Alias
How Delete File from Fortran Code
In Linux, Physical Memory Pages Belong to The Kernel Data Segment Are Swappable or Not
How to Provide Extend-On-Write Functionality for Memory Mapped Files in Linux
Rodbc Not Recognizing My Odbc Settings
How to View Svn Diff in Vimdiff Style in Svn
How to Access Raspberry Pi Qemu Vm via Network
How Can Beaglebone Black Be Used as Mass Storage Device
How to Give File Permission to a Specific User in a Group
Apache Cgi in User Directory "End of Script Output Before Headers"
How to Assign Execute Permission to a .Sh File in Windows to Be Executed in Linux
Installing Oracle Instantclient on Linux Without Setting Environment Variables
Gnu Linker: Alternative to -Version-Script to List Exported Symbols at The Command Line