Files
ncpfs/contrib/libtrace/README
ncpfs archive import 82706139bf Import ncpfs 2.2.1
2026-04-28 20:39:59 +02:00

97 lines
3.7 KiB
Plaintext

Hello everybody,
ltrace does not trace calls made to dynamically loaded objects,
and this made my testing of ncpfs Perl wrapper very hard, as
I was not able to confirm what's going inside without adding
debugging prints into either ncpfs or into generated wrapper...
I found this unacceptable, and so I cooked this code. You can
use it to create wrapper around any library you want, it just
must be dynamic library, not a static one.
Usage is simple:
NCP_TRACE_FILE=demo.trc LD_PRELOAD=./tracencp.so demo.pl
and enjoy demo.trc file.
I hope that in future I'll be able to persuade SWIG to create
trace_in_* and trace_out_* wrappers for me automatically - but
of course you can do it yourself meanwhile.
trace_in_XXX function has same arguments as XXX function, with
two parameters added in front of the list - const char* functionName
and void* caller. trace_out_XXX function has also arguments of
wrapped function - with added int returnValue and void* caller.
So for example for NWDSFreeContext() you have:
NWDSCCODE NWDSFreeContext(NWDSContextHandle ctx);
void trace_in_NWDSFreeContext(const char* name, void* addr, NWDSContextHandle ctx);
void trace_out_NWDSFreeContext(NWDSCCODE err, void* addr, NWDSContextHandle ctx);
You should not modify arguments passed to you - depending on
optimization level your changes may be visible to function you
are wrapping and/or to caller. And you should use logprintf()
in trace_in_* and resprintf() in trace_out_*. These functions
take a care of automatic indenting and printing address of caller.
And of course, currently there are several limitations:
- only i386 version exists... Write your own assembly code, and send me it
if you want this on your architecture.
- you cannot create C wrappers around functions which return 64bit
quantities (if you'll cook wrapper in assembly, you'll find upper
32bits in %edx register).
- on callchain deeper than 256 levels it dies.
- versioned symbols are not properly wrapped with version, they
are wrapped without version information.
- maybe more... Use of weak symbols is intentional feature and not a bug.
Example (this example also shows that context handle is automatically
destroyed when it is no longer referenced from Perl - this is why
I wrote this tracer...):
$ NCP_TRACE_FILE=demo.trc LD_PRELOAD=./tracencp.so demo.pl
NWDSCreateContext() = ok, ctx=ncpfs::NWDSContextHandle=SCALAR(0x80f6408)
NWDSDuplicateContext(ctx) = ok, nctx=ncpfs::NWDSContextHandle=SCALAR(0x80f6444)
$ cat demo.trc
402B593D: NWDSCreateContext() = ...
401E3787: NWDSCreateContextHandle() = ...
401E3242: NWDSInitRequester() = ...
401E22B2: my_iconv() = 0
401E22C0: my_iconv_close() = 0
(cont'd.) ... = 0
401E3377: NWDSSetContext() = ...
401E39B3: my_iconv_open() = 135390952
401E39D6: my_iconv_open() = 135305312
(cont'd.) ... = 0
401E33CA: NWDSSetTransport() = 0
(cont'd.) ... = 0
(cont'd.) ... = 137280664
402B5BB0: NWDSDuplicateContext() = ...
401E37BE: NWDSDuplicateContextHandle() = ...
401E3508: NWDSSetContext() = ...
401E39B3: my_iconv_open() = 135292056
401E39D6: my_iconv_open() = 135291776
(cont'd.) ... = 0
401E360E: NWDSSetContext() = ...
401E39B3: my_iconv_open() = 135404088
401E39D6: my_iconv_open() = 135733664
401E3A05: my_iconv_close() = 0
401E3A22: my_iconv_close() = 0
(cont'd.) ... = 0
(cont'd.) ... = 0
(cont'd.) ... = 136991752
40255E93: NWDSFreeContext() = ...
401E36A1: my_iconv_close() = 0
401E36B5: my_iconv_close() = 0
(cont'd.) ... = 0
40255E93: NWDSFreeContext() = ...
401E36A1: my_iconv_close() = 0
401E36B5: my_iconv_close() = 0
(cont'd.) ... = 0
$
Enjoy,
Petr Vandrovec
vandrove@vc.cvut.cz