2010-01-07 89 views
0

我有一个插件系统在我的项目(在Linux上运行),而这部分是插件有一个“跑”的方法,如:在C++中调试参数损坏?

​​

我打电话给我的插件,去检查我的argv数组(在做了一堆其他的东西之后),并且 数组已损坏。我可以在函数的顶部打印出数值,它们是正确的,但不会在执行过程中。很显然,有些东西正在破坏堆,但是我不知道如何确定什么是覆盖内存。 Valgrind并没有帮助我很多。

示例代码的请求:

我的插件看起来是这样的:

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功能,打破了这一点正是如此:那么

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传递到上面提到的插件。

+0

可以包含代码的样本,使其更容易为我们的同胞,以便用户了解你在做什么? – t0mm13b 2010-01-07 01:21:23

+0

添加了示例代码,因为这个插件非常大,所以它是骨架的,但是这会给你提供问题所在的要点。 – 2010-01-07 01:25:24

+0

我想我们可以告诉问题的本质是什么,但是您已经排除了任何有助于解决问题实际来源的问题。有一百万种不同的东西可能会破坏这个数组,但你遗漏了所有的代码。 – SoapBox 2010-01-07 01:34:19

回答

2

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

在乘车路线downvoted作为OP没有表现出translate_arguments怎么叫,缺乏进一步的信息风险....和误判,如果我的回答是不正确......

希望这有助于 最好的问候, 汤姆。

+0

我同意你的第二部分(为字符串分配存储空间)。按照目前的写法,向量中的指针指向存储在栈上的数据,然后超出范围(arg_str)。在调用translate_arguments之后,可能有一些代码会覆盖堆栈中的空间(局部变量等)。 – Luke 2010-01-07 01:56:16

+0

果然,似乎已经解决了这个问题,谢谢! – 2010-01-07 15:55:35

2

查找如何在调试器中使用内存访问断点。如果你有一个可靠的回购,这将在几秒钟内找出你的问题。在WinDbg中,它是:

ba w4 0x<address> 

其中BA代表“对获得突破”,“W4”是“写4个字节”(64位系统上使用W8)和“地址”显然你的地址”重新看到损坏。 gdb和Visual Studio具有类似的功能。

+0

任何想法你怎么可以用gdb做到这一点?听起来像我所需要的。 – 2010-01-07 01:26:20

+0

看起来像http://stackoverflow.com/questions/58851/can-i-set-a-breakpoint-on-memory-access-in-gdb – 2010-01-07 01:27:32

+0

非常好,谢谢! – 2010-01-07 01:28:22

0

如果Valgrind的和代码检查不帮助你可以尝试电子围栏