Re: [DynInst_API:] ReplaceFunction doesn't work


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

Dyninst collects parameter (and local variable) information from debugging info that may or may not be present in the binary. If your binary was compiled with '-g' then Dyninst should be able to find debug information.

Many system libraries, such as libc, aren't compiled with debug information and thus Dyninst doesn't know about function parameters.

If you want parameter info for system libraries you might be able to install debuginfo files, depending on your distribution. RedHat, for example, has the debuginfo-install command for getting debug info for system binaries.


Note that even if debug info is not present, Dyninst instrumentation should still be able to access parameter values. Dyninst may not know the parameter name, type, or number of parameters, but if you ask for parameter #3, then Dyninst instrumentation should still be able to get that value.

-Matt

On Thu, 2 Apr 2009, Rishikesh Naik wrote:
Hi All,

I am also facing the same problem that getParams() always returns zero
parameters. What's the solution for this?

Thanks,
Rishikesh

On Thu, Apr 2, 2009 at 6:53 PM, Valéria Quadros <valeriaquadros@xxxxxxxxx>wrote:

Hi Matt,

   thanks a lot for your reply. The code is running on a machine with
Ubuntu 2.6.24-19 generic kernel. The dyninstAPI version is 5.2 and the
processor is an intel centrino duo.

   If I replace on "__libc_write" (appImage->findFunction("__libc_write",
writeFuncs) - is that what you mean?), findFunction returns:

 --SERIOUS-- #100: Image: Unable to find function: __libc_write
 ERROR: Unable to find function for __libc_write()

   By the way, the method getParams() returns zero parameter no matter the
function I call. Reading the programmer's guide, I understood it should
return three parameters (fd, buffer, bufflen) when called to the write
function, shouldn't it?

Best regards, Valéria


On Thu, Apr 2, 2009 at 7:04 PM, Matthew Legendre <legendre@xxxxxxxxxxx>wrote:


(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



_______________________________________________
Dyninst-api mailing list
Dyninst-api@xxxxxxxxxxx
https://lists.cs.wisc.edu/mailman/listinfo/dyninst-api


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