我正在开发一个运行以下规格的嵌入式项目:
# uname -a
Linux FFxAV 2.6.30.10 #mvl-avb-0.6 6 月 28 日星期四 17:55:44 EDT 2012 armv5tejl GNU/Linux
# cat /proc/cpuinfo
处理器:ARM926EJ-S rev 5 (v5l)
BogoMIPS:159.74
特点:swp half fastmult edsp java
CPU 实现者:0x41
CPU架构:5TE
CPU 变体:0x1
CPU部分:0x926
CPU 版本:5
$ /usr/local/arm-2007q3/bin/arm-none-linux-gnueabi-gcc --version
arm-none-linux-gnueabi-gcc(CodeSourcery Sourcery G++ Lite 2007q3-51)4.2.1
我正在编译 lldpd (0.6) 以在该平台上使用,并发现了一些新的、有趣的方法来使我的代码出现段错误。
我遇到的问题与 char 数组的分配有关。
如果我这样分配:
char * 选择; opts = (char*)malloc(sizeof(char) * 50);
代码功能正确(实际上在稍后的调用中出现了段错误,但我们不要详述)。
如果我像这样进行分配:
字符选择[49];
在我的任何调试甚至打印之前,代码段错误。这一切都发生在主方法的顶部。
5 int main(int argc, char ** argv){
6
7 fprintf(stderr, "%d\n", __LINE__);
8 char bopts [50] = "H:vhkrdxX:m:4:6:I:C:p:M:P:S:i@ ";
9 bopts[10] = 'g';
10 }
在一个小测试程序中运行良好,但是
1034 char opts [51] = "H:vhkrdxX:m:4:6:I:C:p:M:P:S:i@ ";
lldpd.c 中的段错误
我继续从每个分配中提取程序集:
来自简单的测试程序(功能)
107 char bopts [50] = "H:vhkrdxX:m:4:6:I:C:p:M:P:S:i@ ";
108 8424: e59f3044 ldr r3, [pc, #68] ; 8470 <main+0x78>
109 8428: e24b2036 sub r2, fp, #54 ; 0x36
110 842c: e3a0c032 mov ip, #50 ; 0x32
111 8430: e1a00002 mov r0, r2
112 8434: e1a01003 mov r1, r3
113 8438: e1a0200c mov r2, ip
114 843c: ebffffba bl 832c <_init+0x44>
来自lldpd.c
5061 char opts [51] = "H:vhkrdxX:m:4:6:I:C:p:M:P:S:i@ ";
5062 d414: e59f3918 ldr r3, [pc, #2328] ; dd34 <lldpd_main+0x9d4>
5063 d418: e51b20bc ldr r2, [fp, #-188]
5064 d41c: e0823003 add r3, r2, r3
5065 d420: e24b2043 sub r2, fp, #67 ; 0x43
5066 d424: e3a0c033 mov ip, #51 ; 0x33
5067 d428: e1a00002 mov r0, r2
5068 d42c: e1a01003 mov r1, r3
5069 d430: e1a0200c mov r2, ip
5070 d434: ebfff229 bl 9ce0 <_init+0x344>
到目前为止我还看不出这里出了什么问题。
当在堆上而不是堆栈上分配数组时,程序在尝试在堆栈上分配 sockaddr_un 结构时会出现 seqfaults。
来自un.h
8 struct sockaddr_un {
9 __kernel_sa_family_t sun_family; /* AF_UNIX */
10 char sun_path[UNIX_PATH_MAX]; /* pathname */
11 };
我的假设是这是相同的堆栈数组问题,但我很难弄清楚到底是什么。
无论如何,欢迎提出意见或建议。这几天已经让我发疯了。
看起来编译器将堆栈变量对齐到对齐位置上的end(请参阅
sub r2, fp, #67
指令)。在我看来,这是相当奇怪的,但可能是段错误的解释(尽管我不确定为什么任何代码都会使用字大小访问 char 数组)。如果您可以显示崩溃的确切位置和调用堆栈,它可能会变得更清晰一些。
我认为最简单的解决方案是升级到较新的工具链(2007 年相当旧),看看它是否工作得更好;如果不是,请尝试确保所有本地变量的大小都与 4 字节对齐。