我刚刚注意到我无法让函数返回结构。
我在启用了线程的 ARM32/debian docker 映像上运行它。
这是给我运行时错误的函数:
struct CEC_call des_CEC_call(char * buffy){
char request = buffy[0]; // fails here
buffy+=4;
char obligation = buffy[1];
buffy+=4;
struct CEC_call ceccall;
pepcall.request = request;
pepcall.obligation = obligation;
return ceccall;
}
但是如果我将返回类型更改为void
,则运行没有问题:
void des_CEC_call(char * buffy){
char request = buffy[0]; // doesn't fail here
buffy+=4;
char obligation = buffy[1];
buffy+=4;
struct CEC_call ceccall;
pepcall.request = request;
pepcall.obligation = obligation;
}
返回也适用于任何标准返回类型。
定义结构的标头包含在函数的文件中,尽管即使在同一文件中定义结构,它仍然会崩溃。不知道如何进行调试,任何帮助不胜感激。
编辑:
更多详细信息,基于评论中的建议:
我已经在我的 mac 以及带有 docker 的其他一些非 arm 架构上重新运行了相同的程序,并且它运行没有任何明显的问题。与位移位相关的某些方面与预期略有不同,但没有来自分段错误的运行时错误。我尝试使用各种优化级别运行它,但无济于事。
我以前使用过 GDB,所以我认为这可能会提供一些见解,遗憾的是我无法让它在这个容器上工作。
我确保安装了 GDB 并使用-0g
重新编译了二进制文件。
我用--cap-add=SYS_PTRACE
和--security-opt seccomp=unconfined
运行了 docker.
每次我得到:
warning: Could not trace the inferior process.
Error:
warning: ptrace: Function not implemented
During startup program exited with code 127.
我能够将 GDB 与其他非 arm、非 32 位 docker 映像一起使用,没有任何问题。我认为这足以回答另一个问题,因为我花了很长时间试图让 GDB 在这种环境中工作。
我不确定如何验证其他方式,但是我已经打印出了buffy
指向的地址以及buffy[0]
在前面的函数以及有问题的函数中持有的值。
不带结构返回:
address of buffy = 0xff58b9ec
buffer[0] = ff
address of buffy = 0xff58b9ec
buffer[0] = ff
address of buffy = 0xff58b9ec
buffer[0] = ff
使用结构返回:
address of buffy = 0xff58b9ec
buffer[0] = ff
address of buffy = 0xff58b9ec
buffer[0] = ff
address of buffy = (nil)
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
结构CEC_call
没有任何其他字段。 它可能是某处的缓冲区溢出,但没有任何缓冲区,至少我没有制作。我以前没有使用过QEMU IIRC或valingrad,但会更详细地研究它们。我目前无法进行自然测试,因为我无法访问预期的嵌入式 linux。
struct CEC_call ceccall;
pepcall.request = request;
pepcall.obligation = obligation;
似乎您的变量名称不匹配:ceccall
和pepcall
,并且您返回一个未初始化的变量ceccall
。
我的问题是获得struct CEC_call des_CEC_call(char * buffy)
函数声明的文件的标头未包含在调用文件中。
如果调用函数返回标准类型或 void,则它可以正常工作,但是使用自定义结构返回时,传入的数组指针无效。这最初让我感到困惑,因为我认为由于缺少声明而无法编译它,并且这种分段错误只发生在 arm32 架构上,我没有在 OSX 上崩溃。