2

これは宿題です。特定の回答ではなく、gdb のヘルプが必要です。

私は gdb の経験がまったくなく、端末の経験もほとんどありません。gdb を使用していくつかのコードをデバッグするためにオンラインで簡単な例に従いましたが、例では、gdb はコードを実行したときに問題が発生したことを指摘しました。この割り当てのプロセスを模倣しようとすると、gdb は何も言いません。私はまだ C に慣れていませんが、コードを見ると gdb が何も言っていないことに問題があることがわかります。

ファイルの名前が test.c だとします。ターミナルで gcc test.c と入力すると、存在するのprintf()に存在しないという警告が表示#include <stdio.h>されます。

また、a.out を生成し、./a.out を使用してターミナルで実行しても何も起こりません。端末はメッセージなしで次の入力の準備ができています。gdb ./a.out と入力して実行すると、プログラムが正常に終了したことがわかります。

gdbがエラーを指すようにするために私がしなければならないことを誰かが指摘できますか?

// insertion sort, several errors

int X[10],  // input array
    Y[10],  // workspace array  
    NumInputs,  // length of input array
    NumY = 0;  // current number of 
               // elements in Y

void GetArgs(int AC, char **AV) {
    int I;
    NumInputs = AC - 1;
    for (I = 0; I < NumInputs; I++) X[I] = atoi(AV[I+1]);
}

void ScootOver(int JJ) {
    int K;
    for (K = NumY-1; K > JJ; K++) Y[K] = Y[K-1];
}

void Insert(int NewY) {
    int J;
    if (NumY = 0) { // Y empty so far, 
        // easy case
        Y[0] = NewY;
        return;
    }
    // need to insert just before the first Y
    // element that NewY is less than
    for (J = 0; J < NumY; J++) {
        if (NewY < Y[J]) {
            // shift Y[J], Y[J+1],... rightward 
            // before inserting NewY
            ScootOver(J);
            Y[J] = NewY;
            return;
        }
    }
}

void ProcessData() {
    // insert new Y in the proper place
    // among Y[0],...,Y[NumY-1]
    for (NumY = 0; NumY < NumInputs; NumY++) Insert(X[NumY]);
}

void PrintResults() {
    int I;
    for (I = 0; I < NumInputs; I++) printf("%d\n",Y[I]);
}

int main(int Argc, char ** Argv) {
    GetArgs(Argc,Argv);
    ProcessData();
    PrintResults();
}

編集:コードは私のものではなく、割り当ての一部です

4

2 に答える 2

6

エラーにはさまざまな種類があります。プログラム(コンパイラ、OS、デバッガ)で検出できるものもあれば、検出できないものもあります。

コンパイラは、制約違反を検出した場合にエラーを発行する必要があります(C標準による)。標準準拠モードでない場合は、他のエラーや警告が発生する可能性があります。-Wallおよびオプションを追加すると、コンパイラはより多くのエラー診断を提供し-Wextraます。-O0最適化を有効にすると(さまざまなレベルの最適化を設定することで)、コンパイラーはさらに多くのエラーを検出できる場合-O3がありますが、デバッガーでシングルステップを実行する場合は、オプティマイザーによって最適化が困難になるため、最適化をスキップすることをお勧めします。関連するソース行を表示するデバッガー(一部は並べ替えられる場合があり、一部は削除される場合があります)。

オペレーティングシステムは、不正なポインタ(通常)、システムコールへの不正な引数、または(通常)浮動小数点のゼロ除算に関連するエラーを検出します。

しかし、プログラムをクラッシュさせないものはすべてセマンティックエラーです。そして、これらはそれらを探すために人間の脳を必要とします。

したがって、ブライアンが言うように、ブレークポイントを設定し、プログラムをシングルステップで実行する必要があります。そして、jweyrichが言うように、-gデバッグシンボルを追加するには、でプログラムをコンパイルする必要があります。

変数を調べることができますprint(たとえば、行print Argcにあるコマンドライン引数の数がわかりますrun)。そしてdisplay、各プロンプトの直前に表示されるリストに変数を追加します。のforループを介してデバッグしている場合はInsert、おそらくdisplay Jand display Y[J]、、を実行してからnext、Enterキーを何度も押して、計算の進行状況を確認します。

ブレークポイントが深くネストされている場合は、で「スタックダンプ」を取得できますbacktrace

next次のステートメントに移動します(セミコロンに続く)。step関数呼び出しと関数の最初のステートメントに移動します。また、覚えておいてください。関数をシングルステップで実行して「return」ステートメントに到達した場合は、を使用stepして、呼び出し元のステートメントに次の関数呼び出しを入力します。戻り時に使用nextして、呼び出し元のステートメントを終了します(そして、プロンプトを表示せずに、ステートメント内の残りの関数呼び出しを実行するだけです)。このビットをまだ知る必要はないかもしれませんが、知っている場合は、そこに行きます。

于 2013-01-24T05:42:19.183 に答える
1

からgdb、実行しbreak main、次にrun

そこから、nextまたはstepどこが間違っているかがわかるまで。

于 2013-01-24T05:25:34.707 に答える