::whatthread and MDB modules
By eschrock on Feb 02, 2005
A long time ago I described a debugging problem where it was necessary to determine which threads owned a reader lock. In particular, I used the heuristic that if the address of the rwlock is in a particular thread's stack, then it most likely held by the thread (and can be verified by examining the thread's stack). This works 99% of the time, because you typically have the following:
rw_enter(lock, RW_READER); /\* ... do something ... \*/ rw_exit(lock);
The compiler has to preserve the address of the lock across all the junk in the middle, so it almost always ends up getting pushed on the stack. At described in the previous post, this means a combination of ::kgrep and ::whatis, plus some hand-pruning, to get the threads in question. At the time, I mentioned how nice it would be to have a dedicated command do this dirty work. Now that Solaris 10 has shipped, I finally sat down and gave it a try. In a testament to MDB's well-designed interfaces, I was able to write the entire command in under 5 minutes with just 50 lines of code. On top of that, it runs in a fraction of the time. Rather than searching the entire address space, we only have to look at the stack for each thread. For example:
> c8d45bb6::kgrep | ::whatis c8d45ae4 is c8d45aa0+44, allocated as a thread structure cae92ed8 is in thread c8d45aa0's stack cae92ee4 is in thread c8d45aa0's stack cae92ef8 is in thread c8d45aa0's stack cae92f24 is in thread c8d45aa0's stack > c8d45bb6::whatthread 0xc8d45aa0 >
The simple output allows it to be piped to ::findstack to quickly locate questionable threads. There have been discussions about maintaining a very small set of held reader locks in the thread structure, but it's a difficult problem to solve definitively (without introducing massive performance regressions).
This demonstrates an oft-overlooked benefit of MDB. Though very few developers exist outside of the Solaris group, developing MDB modules is extremely simple and powerful (there are more than 500 commands and walkers in MDB today). Over time, I think I've almost managed to suppress all the painful GDB memories from my college years...