Re: [DynInst_API:] oneTimeCode in an exit callback not working


Date: Wed, 27 Jul 2016 10:38:38 -0700
From: Josh Stone <jistone@xxxxxxxxxx>
Subject: Re: [DynInst_API:] oneTimeCode in an exit callback not working
On 07/27/2016 10:15 AM, Martijn wrote:
> Hi Josh,
> 
> Makes sense. Does that however mean that the retee example in the manual
> is wrong then? There, code is executed in the exit callback to close the
> file handle. The comment behind the continueExecution() suggests that
> such code can still execute.

Yes, I believe that example is wrong.  Using SystemTap to watch
syscall.open and syscall.close, I can see that the mutatee never
actually closes the extra file that was opened.

In practice, this isn't a big deal since the kernel will clean up file
descriptors anyway.  If it had been a FILE*, there may be buffered data
that won't be written out.  In general it's a bad example since it
doesn't actually do what it claims.

This example also falls afoul destructor order for me on Fedora 24,
giving a segfault, as I posted a while ago[1].  It needs to either stop
using a global BPatch or be sure to detach the process before exiting.

[1] https://www-auth.cs.wisc.edu/lists/dyninst-api/2014/msg00180.shtml

> Best,
>   Martijn
> 
> 
> On Jul 27, 2016 18:48, "Josh Stone" <jistone@xxxxxxxxxx
> <mailto:jistone@xxxxxxxxxx>> wrote:
> 
>     On 07/27/2016 01:56 AM, Martijn wrote:
>     > Hello,
>     >
>     > I am trying to use proc->oneTimeCode inside an exit callback. The one
>     > time code adds a function call to finalize stuff in my instrumentation
>     > library.
>     >
>     > The exit callback nicely gets called at the end of the mutee, but the
>     > oneTimeCode does not call my finalize function. I tested the same
>     > oneTimeCode function call outside the exit callback and that works
>     fine.
> 
>     At the time of an exit callback, the process is technically dead.  You
>     may still be able to examine state, but it won't be able to run any
>     code.
> 
> 
>     > My code in short (borrowed from the retee example in the dyninst
>     > manual), simplified to a puts() call:
>     >
>     > static void exitCallback(BPatch_thread* thread, BPatch_exitType) {
>     >     BPatch_process* proc = thread->getProcess();
>     >     BPatch_image* image = proc->getImage();
>     >
>     >     std::vector<BPatch_snippet*> args;
>     >     BPatch_constExpr stringArg("Exiting mutee");
>     >     args.push_back(&stringArg);
>     >     std::vector<BPatch_function*> putsFuncs;
>     >     image->findFunction("puts", putsFuncs);
>     >     BPatch_funcCallExpr putsCall(*putsFuncs[0], args);
>     >
>     >     proc->oneTimeCode(putsCall);
>     >     proc->continueExecution();
>     > }
>     >
>     > int main(int argc, char* argv[]) {
>     >     BPatch_process* proc = bpatch.processCreate(argv[1], (const
>     > char**)(argv + 1));
>     >
>     >     bpatch.registerExitCallback(exitCallback);
>     >
>     >     proc->continueExecution();
>     >     while(!proc->isTerminated())
>     >         bpatch.waitForStatusChange();
>     >
>     >     return EXIT_SUCCESS;
>     > }
>     >
>     > I am running this on Ubuntu 16.04 desktop, using g++ 5.3.1, and the
>     > latest dyninst master (head at commit 895d3fa) from github.
>     > The mutee is a simple C hello world program, compiled with gcc -g.
>     > A full example and makefile to build and run is attached.
>     >
>     > Any input to where I go wrong is greatly appreciated!
>     >
>     > Cheers,
>     >     Martijn
>     >
>     >
>     > _______________________________________________
>     > Dyninst-api mailing list
>     > Dyninst-api@xxxxxxxxxxx <mailto:Dyninst-api@xxxxxxxxxxx>
>     > https://lists.cs.wisc.edu/mailman/listinfo/dyninst-api
>     >
> 

[← Prev in Thread] Current Thread [Next in Thread→]