2

5時間以上実行した後にSIGABRTするプログラムがあります。valgrind でチェックした後のメモリ リークが原因である可能性が最も高いですが、valgrind レポート (単にアドレスと ??? を含む) に基づいて、どの変数が実際にこの問題を引き起こしているかを追跡しています。

valgrind と gdb を使用してステップスルーしようとしています。ただし、(428 ラウンドのループ後) リークに到達するまでに 5 時間かかるため、たとえば loop=428 のときにブレークポイントを設定し、コードにステップインしたいと考えています。どうやってやるの?

以下の簡単なプログラムに基づいて、

a) 変数 'a' の値の変更を追跡する方法は?

b) loop = 428 のときにブレークポイントを設定する方法は?


typedef struct data_attr {
   int a[2500];
}stdata;

typedef struct pcfg{
    stdata *data;
}stConfig;

int funcA(stConfig* pt){  

    int loop = 0;

    while (loop < NUM_NODE){  
        pt->data->a[0] = 1000;
        pt->data->a[0] = 1001;
        loop++;
    }
    return 0;
}

int main(){
    stConfig *p;

    p = (stConfig*) malloc(sizeof(stConfig));
    p->data = (stdata*) malloc (sizeof(stdata));

    funcA(p);

    free(p->data);
    free (p);

    return 0;
}

ubuntu 10.04でvalgrind 3.7を使用しています

@ valgrind 端末、

valgrind -v --vgdb=yes --vgdb-error=0 --tool=memcheck --leak-check=full --leak-resolution=high --num-callers=40 --track-origins=yes --ログファイル=mr3m1n2500_valgrind_0717_1155.txt ./pt m >& mr3m1n2500_logcheck_0717_1155.txt

@ gdb ターミナル 'p' のアドレスを取得しようとしましたが、void が返されました。なぜですか?

> gdb ./pt
(gdb) target remote | vgdb
Remote debugging using | vgdb
relaying data between gdb and process 12857
Reading symbols from /lib/ld-linux.so.2...Reading symbols from /usr/lib/debug/lib/ld-2.11.1.so...done.
done.
Loaded symbols for /lib/ld-linux.so.2
[Switching to Thread 12857]
0x04000850 in _start () from /lib/ld-linux.so.2
(gdb) p $p
$1 = void
(gdb) bt 10
#0  0x04000850 in _start () from /lib/ld-linux.so.2
4

4 に答える 4

3
  1. 変数の値の変化を追跡するために、その変数にウォッチポイントを設定できます。

    あなたの場合、次を使用します。watch p->data->a[index]

  2. 必要な条件でブレークするには、 break を使用できますbreak if loop_counter==428

于 2012-07-17T09:01:05.267 に答える
1

help breakGDBから:

(gdb) ヘルプ ブレーク
指定した行または関数にブレークポイントを設定します。
break [LOCATION] [thread THREADNUM] [if CONDITION]
LOCATION は、行番号、関数名、または "*" とアドレスのいずれかです。
行番号が指定されている場合は、その行のコードの先頭でブレークします。
関数が指定されている場合、その関数のコードの先頭でブレークします。
アドレスが指定されている場合は、その正確なアドレスでブレークします。
LOCATION がない場合、選択したスタック フレームの現在の実行アドレスを使用します。
これは、スタック フレームに戻るときにブレークするのに役立ちます。

THREADNUM は「情報スレッド」からの番号です。
CONDITION はブール式です。

1 つの場所で複数のブレークポイントが許可され、条件付きの場合に役立ちます。

ブレークポイントを扱う他のコマンドの情報については、「ヘルプ ブレークポイント」を実行してください。

条件にブレークポイントを設定するにはbreak if condition、あなたのケースbreak if loop_counter == 428などで , を使用します。

于 2012-07-17T08:51:04.353 に答える
0

最初の質問では、変数'a'の値の変化を追跡する方法は?「時計」をご利用ください、

watch [-l|-location] expr [thread threadnum] [mask maskvalue]

式のウォッチポイントを設定します。式exprがプログラムによって書き込まれ、その値が変更されると、gdbは壊れます。このコマンドの最も簡単な(そして最も一般的な)使用法は、単一の変数の値を監視することです。

      (gdb) watch foo

JoachimPileborgが2番目の質問の答えを持っています。

3番目の質問では、行で休憩を設定する必要があります

 p->data = (stdata*) malloc (sizeof(stdata));

次に、「p」の値を出力してみます。

于 2012-07-17T08:56:10.263 に答える
0

a)そのループのブレークポイントを設定するには、次のようなことができます:

if(loop == 428)
    int nop = 0;

次に、行 int nop = 0 にブレークポイントを設定します。このように、プログラムはその行が実行されたときにのみ停止します。これはループ 428 で発生します。

b) これについてはよくわかりません。「p」の値をどこで調べようとしていますか?

于 2012-07-17T08:15:16.220 に答える