1

我正在开发一个使用以下规格运行的嵌入式项目:

# unname -a

Linux FFxAV 2.6.30.10 #mvl-avb-0.6 Thu Jun 28 17:55:44 EDT 2012 armv5tejl GNU/Linux

# 猫 /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 数组的分配有关。

如果我以这种方式分配:

字符 * 选择;opts = (char*)malloc(sizeof(char) * 50);

代码正常运行(实际上在以后的调用中会出现段错误,但我们不要停留)。

但是,如果我像这样进行分配:

字符选择[49];

在我的任何调试甚至打印之前代码段错误。这一切都发生在 main 方法的顶部。

  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 结构时会出错。

来自 un.h

8  struct sockaddr_un {
9      __kernel_sa_family_t sun_family; /* AF_UNIX */
10     char sun_path[UNIX_PATH_MAX];   /* pathname */
11 };

我的假设是这是同一个堆栈数组问题,但我很难弄清楚到底是什么。

无论如何,感谢您的意见或建议。这已经让我发疯了几天了。

4

1 回答 1

0

看起来编译器将堆栈变量对齐以在对齐的位置结束(参见sub r2, fp, #67说明)。这是非常奇怪的 IMO,但可能是段错误的解释(尽管我不确定为什么任何代码都会使用字长访问 char 数组)。如果您可以显示崩溃的确切位置和调用堆栈,它可能会变得更清晰一些。

我认为最简单的解决方案是升级到更新的工具链(2007 年相当旧),看看它是否效果更好;如果不是,请尝试确保所有本地变量的大小都对齐到 4 个字节。

于 2012-07-16T16:57:59.150 回答