1

次の仕様で実行される組み込みプロジェクトに取り組んでいます。

# うなめ -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)

ボゴMIPS : 159.74

機能 : swp ハーフ 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) をコンパイルしていますが、コードを segfault にする新しい興味深い方法を発見しました。

私が経験している問題は、char 配列の割り当てに関係しています。

そのような方法で割り当てる場合:

char * オプション; opts = (char*)malloc(sizeof(char) * 50);

コードは正しく機能します (実際には、後の呼び出しで segfaults が発生しますが、詳しく説明する必要はありません)。

ただし、次のように割り当てを行う場合:

char オプション[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 構造体を割り当てようとすると、プログラムで seqfault が発生します。

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 ですが、segfault の説明になる可能性があります (ただし、コードがワード サイズを使用して char 配列にアクセスする理由はわかりません)。クラッシュの正確な場所とコール スタックを示すことができれば、もう少し明確になるかもしれません。

最も簡単な解決策は、新しいツールチェーン (2007 年はかなり古い) にアップグレードし、それがうまく機能するかどうかを確認することだと思います。そうでない場合は、すべてのローカル変数のサイズが 4 バイトに揃えられていることを確認してください。

于 2012-07-16T16:57:59.150 に答える