Отладка искажения параметра в C ++? - PullRequest
0 голосов
/ 07 января 2010

У меня есть система плагинов в моем проекте (работающем на Linux), и часть этого заключается в том, что у плагинов есть метод «запуска», такой как:

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

Я вызываю свой плагин и иду, чтобы проверить мой массив argv (после выполнения множества других вещей), и массив поврежден. Я могу напечатать значения в верхней части функции, и они верны, но не позже при выполнении. Очевидно, что-то портит кучу, но Я в недоумении, как я могу попытаться точно определить, что перезаписывает эту память. Вальгринд не очень помог мне.

Пример кода по запросу:

Мой плагин выглядит примерно так:

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]);
  }
}

Это связано с системой, которая предоставляет его Python, поэтому я могу называть эти плагины функциями Python. Поэтому я беру строковый параметр в свою функцию python и разбираю его таким образом:

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

Полученные argc и argv затем передаются плагину, упомянутому выше.

Ответы [ 3 ]

2 голосов
/ 07 января 2010

Как звонить translate_arguments? Чего не хватает ...

Подготавливает ли он массив указателей на символы перед вызовом функции run в плагине, поскольку функция run имеет параметр char *argv[]?

Это похоже на строку, которая вызывает проблемы ... судя по коду

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

Вы намереваетесь выделить указатель на указатель на символ, двойной указатель, но, похоже, приоритет кода немного перепутан? Вы пробовали это так:

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

Кроме того, в вашем цикле for, как показано ... вы не выделяете место для самой строки, содержащейся в векторе ...?

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]);

С риском получить отрицательное голосование, так как ФП не показал, как вызывается translate_arguments, и ему не хватает дополнительной информации .... и неправильно оценил, если мой ответ неверен ...

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

2 голосов
/ 07 января 2010

Узнайте, как использовать точки останова доступа к памяти с вашим отладчиком. Если у вас есть надежный репо, это определит вашу проблему в считанные секунды. В windbg это:

ba w4 0x<address>

Где ba означает «перерыв при доступе», «w4» означает «запись 4 байта» (используйте w8 в 64-битной системе), а «address» - это, очевидно, адрес, который вы видите поврежденным. GDB и Visual Studio имеют схожие возможности.

0 голосов
/ 07 января 2010

Если проверка Valgrind и кода не помогает, вы можете попробовать электрический забор

...