Re: [DynInst_API:] ReplaceFunction doesn't work


Date: Thu, 2 Apr 2009 17:04:41 -0500 (CDT)
From: Matthew Legendre <legendre@xxxxxxxxxxx>
Subject: Re: [DynInst_API:] ReplaceFunction doesn't work

(I'm going to cc this to bugs@xxxxxxxxxxx, which would be a better place for this question).

After a quick glance at your code, nothing jumps out at me as incorrect. What OS and Platform are you running on? If Linux, what distribution?

Also, if you're using Linux, does doing the replace on "__libc_write" work?

-Matt

On Thu, 2 Apr 2009, Valéria Quadros wrote:
Hello,
 I have a code which is supposed to change the behavior of a function
(write call). I generated a shared library with the new write method and
link it against my mutatee. When I compile and execute the mutator,
everything seems to be ok; however, the new write method is not called. The
library code is:

#include<stdio.h>
#include<sys/types.h>

ssize_t myWrite(int fd, const void *buf, size_t count) {
   fprintf(stderr, "hello");
   return 0;
}

The library was generated with the commands:
gcc -fPIC -g -c -Wall myLib.c -o myLibObj.o
gcc -shared -Wl,-soname,libmyLib.so.1 -o libmyLib.so.1 myLibObj.o -lc -ldl

The mutatte code is:

#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main() {
   int fd = open("wwopen.txt" , O_WRONLY|O_CREAT, 0666);

   int res = write(fd, "see you", 7);

   printf("Written %d bytes", res);

   return 1;
}

It was compiled with the command:
gcc -g -o wwopen wwopen.c libmyLib.so.1

The mutator code is:
#include<stdio.h>

#include "BPatch.h"
#include "BPatch_process.h"
#include "BPatch_function.h"
#include "BPatch_Vector.h"
#include "BPatch_thread.h"

bool replaceWrite(BPatch_process *app, BPatch_image *appImage, int rate) {
   int res;
   char name[128];
   unsigned int i;

   BPatch_Vector<BPatch_function *> myFuncs;
   appImage->findFunction("myWrite", myFuncs);
   fprintf(stderr, "myWrite size: %d\n", myFuncs.size());
   BPatch_Vector<BPatch_localVar *> *myparams = myFuncs[0]->getParams();
   fprintf(stderr, "\nParams size: %d", myparams->size());

   // (1) Locate the write call
   BPatch_Vector<BPatch_function *> writeFuncs;
   appImage->findFunction("write", writeFuncs);
   if(writeFuncs.size() == 0) {
       fprintf(stderr, "ERROR: Unable to find function for write()\n");
       return false;
   }
   fprintf(stderr, "\nWrite size: %d\n", writeFuncs.size());

   for(i = 0; i < writeFuncs.size(); i++) {
       writeFuncs[i]->getName(name, 128);
       fprintf(stderr, "\nIsShared1: %d", writeFuncs[i]->isSharedLib());
       fprintf(stderr, "\nWrite1 name: %s\n", name);

       BPatch_Vector<BPatch_localVar *> *params =
writeFuncs[i]->getParams();
       fprintf(stderr, "\nParams size: %d", params->size());
   }

   res = app->replaceFunction(*writeFuncs[0], *myFuncs[0]);

   fprintf(stderr, "\nReplace res: %d", res);

   return true;
}

pid_t createDynProcess(const char *path, const char **argv, int rate) {
   BPatch bPatch;
   bool res;

   BPatch_process *app = bPatch.processCreate(path, argv);
   if(!app) {
       perror("createProcess");
       return -1;
   }
   fprintf(stderr, "\nPassei do processCreate");
   BPatch_image *appImage = app->getImage();

   res = app->loadLibrary("libmyLib.so.1", true);
   if(res == true)
       fprintf(stderr, "\nOK - library loaded");
   else
       fprintf(stderr, "\nNon-OK");

   fprintf(stderr, "\nInstrumenting write...\n");
   res = replaceWrite(app, appImage, rate);
   if (!res) {
       fprintf(stderr, "ERROR: failed to instrument mutatee\n");
       return -1;
   }

   // Continue the execution...
   fprintf(stderr, "\nContinuing execution and waiting for termination\n");
   res = app->continueExecution();
   fprintf(stderr, "\nContinue Execution: %d", res);
   while (!app->isTerminated())
       bPatch.waitForStatusChange();
   printf("\nDone.\n");

   return app->getPid();
}

int main() {
   const char *procArgv[2];
   procArgv[0] = const_cast<char*>("wwopen_temp.txt");
   procArgv[1] = NULL;
   int rate = 2;

   int pid =
createDynProcess(strdup("/home/valeria/dyn_write_test/wwopen"), procArgv,
rate);

   return pid;
}

It was compiled with the command:
g++ -Wall -I /usr/local/dyninst/include -L
/usr/local/dyninst/i386-unknown-linux2.4/lib -ldyninstAPI -g -o teste
teste.C

I don't know where the mistake is. I hope somebody can help me.

Best regard, Valeria

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