Search this site


Metadata

Articles

Projects

Presentations

GDB for poking at libc to test random things

I wanted to test something quickly out in C, but didn't want to write the 5 line of code to do it. Having done some fun ruby debugging with gdb recently, I decided to go with that.
% gdb -q `which sleep` --args `which sleep` 60000
(gdb) break nanosleep
(gdb) run
Starting program: /bin/sleep 60000
[Thread debugging using libthread_db enabled]
[New Thread 0x7f8c40bc46f0 (LWP 6504)]
[Switching to Thread 0x7f8c40bc46f0 (LWP 6504)]

Breakpoint 1, 0x00007f8c404f7ce0 in nanosleep () from /lib/libc.so.6
(gdb) call strcspn("hello world", "w")
$1 = 6
I don't know why I didn't think about this before. This is nicely useful, allowing me to easily test any simple function call unrelated.

libc's tree functions, function pointers, and bdb.

Whoever wrote the tsearch/tfind/tdelete/twalk functions for libc clearly stopped thinking about how it would be used. The only way I can see to iterate the tree is to use twalk, which doesn't let you pass any extra arguments to your provided action method.

This sucks if, for example, you wanted to get a list of all entries in the tree in a threadsafe or multiplicity-safe way.

Some workarounds include:

  • Every time you insert, add the same structure to an array.
  • Use something that supports sane iteration (bdb, for example).
I looked into using bdb for some things, but the tree I wanted to iterate over most was a structure that held, among other things, a function pointer. Function pointers are magical and special and are held in a place in memory you can't simply make a copy of. If you try to store a function pointer in an in-memory BDB database, the value that comes out of your query will be different than the function pointer.

This bdb code sample attempts to store a function pointer in bdb. The output is:

stored: 607a70
actual: 4005e8
The value changed because copying a function pointer doesn't work.

There's a workaround here that might be useful - dlopen(). Any functions I want to store in bdb, I would store by string name and fetch the function pointer with dlsym().

This dlopen example shows how to dlopen yourself and fetch a function by string name.

Fun with pointers.