[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