3

GDB を使用して次の C プログラムをデバッグしようとしています。

// Program to generate a user specified number of 
// fibonacci numbers using variable length arrays
// Chapter 7  Program 8   2013-07-14

#include <stdio.h>

int main(void)
{
    int i, numFibs;
    printf("How many fibonacci numbers do you want (between 1 and 75)?\n");
    scanf("%i", &numFibs);

    if (numFibs < 1 || numFibs > 75)
    {
        printf("Between 1 and 75 remember?\n");
        return 1;
    }

    unsigned long long int fibonacci[numFibs];

    fibonacci[0] = 0;  // by definition
    fibonacci[1] = 1;  // by definition

    for(i = 2; i < numFibs; i++)
        fibonacci[i] = fibonacci[i-2] + fibonacci[i-1];

    for(i = 0; i < numFibs; i++)
        printf("%llu ", fibonacci[i]);

    printf("\n");

    return 0;
}

私が抱えている問題は、次を使用してコードをコンパイルしようとするときです。 clang -ggdb3 -O0 -Wall -Werror 7_8_FibonacciVarLengthArrays.c

作成された a.out ファイルで gdb を実行しようとすると、プログラムの実行がステップ実行されます。fibonacci[] 配列が宣言された後はいつでも、fibonacci <value optimized out>次のように入力します。意味のあるデータが含まれていないようです)。

-O0 フラグが使用されているときに、clang がこの配列を最適化しているように見えるのはなぜですか?

gcc を使用してこのコードをコンパイルすると、GDB を使用すると値が期待どおりに表示されます。

ありがとうございました。

4

3 に答える 3

3

使用しているclangのバージョンについては言及していません。3.2 と最近の SVN インストール (3.4) の両方で試してみました。

2 つのバージョンで生成されたコードは非常によく似ていますが、デバッグ情報が異なります。gdb でフィボナッチを調べようとすると、clang 3.2 (デフォルトの ubuntu 13.04 インストールに由来する) でエラーが発生します。

fibonacci = <error reading variable fibonacci (DWARF-2 expression error: DW_OP_reg operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.)>

clang 3.4 でコンパイルされたコードでは、すべて正常に動作します。どちらの場合も、配列は「最適化」されていません。スタックに明確に割り当てられています。

したがって、あなたが見ている奇妙な点は、実際のコードよりもデバッグ情報の発行に関係しているのではないかと思います。

于 2013-10-06T16:11:31.567 に答える
2

gdb は、スタックに割り当てられた可変長配列のデバッグをまだサポートしていません。https://sourceware.org/gdb/wiki/VariableLengthArrayを参照してください

コンパイル時定数または malloc を使用してフィボナッチを割り当て、gdb から見えるようにします。

配列の初期化時にGDBが「現在のコンテキストにシンボルがありません」と報告するも参照してください

于 2013-10-07T16:43:05.807 に答える
1

clang は配列を「最適化」していません。配列はスタック上で可変長配列として宣言されるため、alloca()その宣言に到達したときに明示的に割り当てる必要があります ( で使用されるものと同様の手法を使用)。アレイの開始アドレスは、そのプロセスが完了するまで不明です。

于 2013-10-06T17:38:24.140 に答える