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


Date: Wed, 27 Jul 2016 23:48:34 +0200
From: Martijn <martijn@xxxxxxxxxxxxxxxxx>
Subject: Re: [DynInst_API:] oneTimeCode in an exit callback not working

Hi Josh,

Clear. So as a general rule: don't rely on instrumentation code to run in an exit callback (and don't use a global bpatch object while you're at it). Would be good to explicitly add that to the manual.

Thanks,
 Martijn


On Jul 27, 2016 7:38 PM, "Josh Stone" <jistone@xxxxxxxxxx> wrote:
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→]