0

I've got a plugin system in my project (running on linux), and part of this is that plugins have a "run" method such as:

void run(int argc, char* argv[]);

I'm calling my plugin and go to check my argv array (after doing a bunch of other stuff), and the array is corrupted. I can print the values out at the top of the function, and they're correct, but not later on in the execution. Clearly something is corrupting the heap, but I'm at a loss of how I can try to pin down exactly what's overwriting that memory. Valgrind hasn't helped me out much.

Sample code by request:

My plugin looks something like this:

void test_fileio::run(int argc, char* argv[]) {
  bool all_passed = true;

  // Prints out correctly.
  for (int ii=0; ii < argc; ii++) {
    printf("Arg[%i]: %s\n", ii, argv[ii]);
  }

  <bunch of tests snipped for brevity>

  // Prints out inccorrectly.
  for (int ii=0; ii < argc; ii++) {
    printf("Arg[%i]: %s\n", ii, argv[ii]);
  }
}

This is linked into a system that exposes it to python so I can call these plugins as python functions. So I take a string parameter to my python function and break that out thusly:

char** translate_arguments(string args, int& argc) {
  int counter = 0;
  vector<char*> str_vec;

  // Copy argument string to get rid of const modifier
  char arg_str[MAX_ARG_LEN];
  strcpy(arg_str, args.c_str());

  // Tokenize the string, splitting on spaces
  char* token = strtok(arg_str, " ");
  while (token) {
    counter++;
    str_vec.push_back(token);
    token = strtok(NULL, " ");
  }

  // Allocate array
  char** to_return = new char*[counter];
  for (int ii=0; ii < counter; ii++)
    to_return[ii] = str_vec[ii];

  // Save arg count and return
  argc = counter;
  return to_return;
}

The resulting argc and argv is then passed to the plugin mentioned above.

trincot
  • 317,000
  • 35
  • 244
  • 286
gct
  • 14,100
  • 15
  • 68
  • 107
  • Can you include a sample of the code to make it easier for us fellow-SO users to understand what you are doing? – t0mm13b Jan 07 '10 at 01:21
  • Sample code added, it's skeletal because this plugin is quite large, but this gives you the gist of what the problem is. – gct Jan 07 '10 at 01:25
  • I think we can tell what the nature of the problem is, but you've left out anything that would help as to the actual source of the problem. There are a million different things that could corrupt this array but you've left out all of that code. – SoapBox Jan 07 '10 at 01:34
  • Damn...the OP poster left...that should be tagged as homework.... – t0mm13b Jan 07 '10 at 01:37
  • Sorry guys the source code is wayy to large to post in it's entirety. I'm mostly looking for tips on how to debug this sort of thing rather than specific help in this instance. – gct Jan 07 '10 at 05:40

3 Answers3

2

Lookup how to use memory access breakpoints with your debugger. If you have a solid repo, this will pinpoint your problem in seconds. In windbg, it's:

ba w4 0x<address>

Where ba stands for "break on access", "w4" is "write 4 bytes" (use w8 on a 64 bit system) and "address" is obviously the address you're seeing corrupted. gdb and Visual Studio have similar capabilities.

Terry Mahaffey
  • 11,775
  • 1
  • 35
  • 44
2

How does translate_arguments get called? That is missing...

Does it prepare an array of pointers to chars before calling the run function in the plugin, since the run function has parameter char *argv[]?

This looks like the line that is causing trouble...judging by the code

// Allocate array
char** to_return = new char*[counter];

You are intending to allocate a pointer to pointer to chars, a double pointer, but it looks the precedence of the code is a bit mixed up? Have you tried it this way:

char** to_return = new (char *)[counter];

Also, in your for loop as shown...you are not allocating space for the string itself contained in the vector...?

for (int ii=0; ii < counter; ii++)
    to_return[ii] = str_vec[ii];

// Should it be this way...???

for (int ii=0; ii < counter; ii++)
    to_return[ii] = strdup(str_vec[ii]);

At the risk of getting downvoted as the OP did not show how the translate_arguments is called and lacking further information....and misjudging if my answer is incorrect...

Hope this helps, Best regards, Tom.

t0mm13b
  • 34,087
  • 8
  • 78
  • 110
  • I agree with your second part (allocating storage for the strings). As currently written, the pointers in the vector point to data that is stored on the stack that then goes out of scope (arg_str). After translate_arguments is called, there is probably some code that ends up overwriting that space in the stack (local variables, etc). – Luke Jan 07 '10 at 01:56
0

if valgrind and code inspection dont help you could try electric fence

pm100
  • 48,078
  • 23
  • 82
  • 145