[Ltrace-devel] nested library calls and right-hand params

Petr Machata pmachata at redhat.com
Tue Nov 2 16:49:02 UTC 2010


Hi,

No canadian crosses this time around, this should be easily reproducible 
on any old linux box.

Let's have the following code in zz.c

#ifdef LIB
void work (char *x) { *x = 'x'; }
void call (char *x, char* y, void (*cb) (char *)) {
   cb (y);
   *x = (*y)++;
}
#else
void work (char *x);
void call (char *x, char* y, void (*cb) (char *));
#endif

#ifndef LIB
int main () {
   char x[10] = {};
   char y[10] = {};
   call (x, y, work);
   puts (x);
   puts (y);
}
#endif

And the following config in zz.conf:
void work(+string);
void call(+string, string, addr);
int puts(string);

Compile it like so:
gcc -DLIB -shared -fpic ~/zz.c -o libzz.so
gcc -ULIB ~/zz.c ./libzz.so -o zz

And run under ltrace (output trimmed):
$ ./ltrace -F zz.conf ./zz
call( <unfinished ...>
work("x") = <void>
<... call resumed> "y", "y", 0x00400548) = <void>
puts("x") = 2
puts("y") = 2
+++ exited (status 2) +++

Notice how "call" is listed with two "y" params, where it should list 
"x" and "y" (as the following puts calls correctly show).  The problem 
here is that the register set is preserved in struct Process, not in 
struct callstack_element, and so is overwritten when nested call appears 
which has right-hand parameters too.

PM



More information about the Ltrace-devel mailing list