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
> >
>
|