【问题标题】:Corrupted arguments passed to function传递给函数的参数损坏
【发布时间】:2012-03-29 13:23:51
【问题描述】:

我正在用 C 为嵌入式设备(STM32)编写一个可执行文件。经过一些调试,我将其简化为这个函数:

char * parse(char * start)
{
    int i = 0;
    char command[20];
    print(start);
}

由于某种原因,当我调用此函数时,参数start 已损坏。现在,如果我注释掉 command 初始化,我可以让它工作:

char * parse(char * start)
{
    int i = 0;
    // char command[20];
    print(start);
}

注释掉command,一切正常。我可能会用完内存。但是这个程序很小,通过检查堆栈指针寄存器,我可以确认我还有很多 RAM 空间。

这里可能出了什么问题?一个损坏的编译器? (我正在为 ARM 使用重新编译的 GCC 版本,称为 Yagarto。)

【问题讨论】:

  • print() 是做什么的?我怀疑您的错误可能在其中(或者它正在输入它无法处理的输入)。
  • 请注意parse() 的返回类型为char*,但return 没有任何内容。
  • 有些东西正在破坏堆栈。当您注释掉 command 时,您正在注释掉堆栈上 20 个字节的分配,这意味着您的堆栈粉碎代码可能会在一些不同的内存位上呕吐。发布 print() 的代码。我认为错误就在那里。
  • 我猜你应该分享你的 print 实现,除非它太大了。
  • @Randomblue - 理想情况下显示所有代码。如果它很大,您可以使用 pastebin 或 github 上的 gist。它极不可能是编译器。如果您想减少这种可能性,请下载 LeafLabs Maple IDE,并使用埋在其中的 gcc toochain。 gdb 是否适用于您的系统?如果是这样,请在开始时设置数据监视。

标签: c embedded


【解决方案1】:

您很可能处于未定义行为的领域,因为您在程序中在其他地方做了错事。它在某些情况下工作的事实绝不会使未定义的行为可接受:-)

可能是您覆盖了内存,或者您的字符串不是以 null 结尾的,或者是其他一百个原因。

【讨论】:

    【解决方案2】:

    您以某种方式破坏了parse 函数的堆栈。注释掉 command 变量的声明将删除堆栈中 20 字节的分配,如果您保留它,则会隐式发生。

    您可以在您的程序上尝试 Valgrind 以找出损坏发生的位置吗?

    另外,print 函数是什么?尝试在这两种情况下打印start 的值

    printf("%p\n", start);
    

    你可以在内存中parse指向的地址找到你的函数栈

    【讨论】:

    • 我没有printf。出于这个原因,我创建了自己的print。我没有 Valgrind,但我有 GDB,如果有帮助的话。
    • start 的值是否在 before 调用 parseinside parse 之间变化?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    • 2020-05-20
    • 2021-04-18
    • 2015-07-05
    相关资源
    最近更新 更多