0

申し訳ありませんが、コードを特定することはできませんが、私が見ている問題は異常です。文字列の値は、他の無関係なコードに応じて変更されているようです。たとえば、以下で渡される引数の値は、fprintf()呼び出しの1つまたは2つをコメントアウトするかどうかに応じて変更されます。最後のfprintf()までに、値は通常完全に空になります(いいえ、引数を直接変更していないことを確認しました... fprintf()をコメントアウトするか、別のfprintf()を追加するだけです。文字列の値は特定の時点で変更されます!):

static process_args(char *arg) {
    /* debug */
    fprintf(stderr, "Function arg is %s\n", arg);

    ...do a bunch of stuff including call another function that uses alloc()...

    /* debug */
    fprintf(stderr, "Function arg is now %s\n", arg);    
}

int main(int argc, char *argv[]) {
    char *my_arg;

    ... do a bunch of stuff ...

    /* just to show you it's nothing to do with the argv array */
    my_string = strdup(argv[1]);

    /* debug */
    fprintf(stderr, "Argument 1 is %s\n", my_string);

    process_args(my_string);
}

周りにはもっと多くのコードがあるので、誰かに私のプログラムをデバッグするように頼むことはできません-私が知りたいのは、このような文字列が無関係のコードに基づいてメモリを変更または上書きする理由をデバッグする方法です。私の記憶は限られていますか?スタックが小さすぎますか?どうすればわかりますか?問題を追跡するために他に何ができますか?私のプログラムは巨大ではありません。1000行のコードがgiveまたはtakeし、動的にリンクされた外部ライブラリが2つあるようなものですが、異常なことは何もありません。

ヘルプ!TIA!

4

4 に答える 4

6

単純:

  1. Valgrind、特にmemcheckの使い方を学ぶ
  2. ブレークポイントと変数検査を含むGDBの使用方法を学ぶ
  3. 練習は完璧を作る。

それはそれをソートする必要があります。GCCのオプションを使用してライブラリをコンパイルして-gください。これにより、デバッグシンボルが保持されるため、デバッグ出力がよりわかりやすくなります。

于 2010-05-17T03:24:20.667 に答える
2

考慮すべき2つのケースがあります。

  1. arg変数は、の開始と終了の間で値を変更しますprocess_args
  2. arg同じままですが、それが指す文字列が変更されます。

説明とコードは2つを区別しませんが、2つのうちどちらが実際に起こっているかを知ることは重要です。

これは答えを明らかにします:

fprintf(stderr, "Function arg is %s (%p)\n", arg, (void *)arg);
... do bunch of stuff ...
fprintf(stderr, "Function arg is now %s (%p)\n", arg, (void *)arg);

ほとんどの場合arg、変更されていません(つまり、ケース2があります)。もしそうなら、何かがあなたが割り当てた文字列を破壊しています。すでに提案されているが、Linux、AIX、MacOSXでのみ利用可能なValgrindは、問題を見つける可能性が50:50しかない。本当に必要なのはGDBウォッチポイントです。最初にブレークポイントを設定しprocess_args、一度ヒットする(gdb) watch *(long*)argと、実行しcontinueます。GDBは、何かが書き込まれると停止します*arg(実際には、次の命令で停止します)。次に、(gdb) whereコマンドを使用して何が起こっているかを把握します。

実際にargその値を変更している場合(ケース1)、デバッグが難しい可能性があり、ある種のスタックの破損、またはプラットフォームのプロシージャ呼び出し規約への違反を示しています。Valgrindはおそらくそれをまったく助けないでしょう。これは、あなたが説明した動作とより一致しています。無関係なコードをコメントアウトすると、バグがシフトします。

ただし、実際のプラットフォームが何であるかを明らかにしていないため、ケース1のデバッグについてこれ以上アドバイスすることはできません。

于 2010-05-17T03:57:14.597 に答える
1

ユーザーレベルのアプリケーションを作成している場合、Valgrindは、メモリリーク、バッファオーバーフローなどのメモリの問題を検出するのに適しています。クイックスタートガイドは次のとおりです。http://valgrind.org/docs/manual/QuickStart.html

于 2010-05-17T03:32:50.103 に答える
0

開発ツールは提供しませんが、プログラマーの90%が、これを処理できるデバッガーを備えたIDEを既に使用している場合は、新しいツールは必要ありません。文字列を保持しているメモリのチャンクに監視を設定し、コードをステップ実行して、文字列がいつ変更されるかを確認します。

于 2010-05-17T03:35:40.623 に答える