Aprobe 5

9. How can I log a parameter passed to a library function like strdup() when there's no debug information available?

If no debug information about a target program is available from its
compiler, then a probe can always revert to low-level primitives.
This means all parameters would be nameless and assumed to be of type 'int'
so only positional ($1, $2, etc.) references would be allowed.

If you know the type layout of a parameter then you can always cast it to
the right type.  This trick is useful no matter what was the program's
original source language.

In this case, strdup() function has no debug information but we know it has
a string parameter, so we'll cast its parameter $1 to a string.  Similarly,
time.h says that nanosleep() takes 2 structures (by reference) so we'll log
these parameters by casting $1 and $2 to a similar looking structure type.

The probe: strdup.spc

typedef struct   /* has same layout as my expected parameter type */
   int seconds;
   int nanosecs;
} my_own_struct;

probe thread
   probe "strdup()" in "libc.so"
         //* Cast $1 to a string using a handy macro defined in probe API:
         log ("Got strdup(", sp_StringValue($1), ")");
   probe "nanosleep()" in "libc.so"
         //* Cast $1, $2 to my_own_struct, since I happen to know its layout:
         log ("Got nanosleep(", *(my_own_struct *)($1), 
                                *(my_own_struct *)($2), ")");

Main test: main.c

#include <string.h>
#include <time.h>

static struct timespec three_sec = { 3, 0 };   /* { seconds, nanosecs } */

int main (int argc, char **argv)
   char   name[] = "ocsystems";
   char * dup;
   int    rc;
   struct timespec remain = {123, 456};
   dup = strdup( name );
   rc  = nanosleep( &three_sec, &remain );

Compile the main.c program to create main.exe:

gcc -g main.c -o main.exe

Compile the main.spc probe to create main.usm:

spc -t linux:x86 -x -x /lib/tls/libc.so.6 main.exe main.spc

The result:

Use sptool to run main.exe program with main.usm probe applied to it.

sptool -u main.usm -if main.exe

Got strdup(ocsystems)
Got nanosleep({
  seconds = 3
  nanosecs = 0
  seconds = 123
  nanosecs = 456