2016-12-21 7 views
2

私は、次のコード(source)持っている:私はgcc -g main.c -o main -lpthreadでコンパイル単純なPthreadルーチンのGDBブレークポイント?

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h> 

#define NUM_THREADS 5 

void *PrintHello(void *threadid) { 
    long tid; 
    tid = (long)threadid; 
    printf("Hello World! It's me, thread #%ld\n", tid); 
    pthread_exit(NULL); 
} 

int main(int argc, char *argv[]) { 
    pthread_t threads[NUM_THREADS]; 
    int rc; 
    long t; 
    for (t=0; t<NUM_THREADS; t++) { 
    printf("In main: creating thread %ld\n", t); 
    rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); 
    if (rc) { 
     printf("ERROR; return code from pthread_create() is %d\n", rc); 
     exit(-1); 
    } 
    } 

    // wait for all threads to die 
    pthread_exit(NULL); 
} 

を。私はデバッグにGDBを使用しています。私が欲しいのは、PrintHelloの2行目、つまりtid = (long)threadidにブレークポイントを置き、そこに実行を止めて(スレッドが何であれ)、変数threadidの値を見てみましょう。

私はEmacsのGDB実装でこれを実現したいと思っています。この問題の目的は、単にGDBと考えることができます(Emacs内で動作することを心配しないでください)。これまでのところ私は、目的の行にブレークポイントを置くことができ、時にはプログラムはである現在の行を示す小さな矢印は確かにこの行で停止しない:私はGDBプロンプトに入力するときしかし

arrow

print threadid私は戻ってNo symbol "threadid" in current context.取得し、矢印は、私がメインに設定され、いくつかのブレークポイント()に即座にジャンプ:

im2

私の推測では、プログラムの実行の「一時停止」は、メインスレッドのために起こりますので、この問題が発生したということですそれは実行中のスレッドではありませんPrintHelloPrintHelloはスレッドtによって実行されます。これはGDBによって一時停止されたスレッドではないため、helloワールドメッセージを出力し、すぐに存在します。 print threadidと入力すると、このスレッドはすでに死んでおり、プログラムはmain()に戻ります。したがって、その結果です。

break <LineNumber> thread <ThreadID>のようなものを入力して解決しようとしましたが、このプログラムでは作成されたスレッドが1秒間続きます。ですから、私は実際にはinfo threadがメインスレッド以外の何かを示す時点に決していません。メインスレッドと新しく作成されたスレッドがあるPrintHelloを実行している時点でプログラムを「キャッチ」することは、人為的には不可能です。この状況は数マイクロ秒と推測されます。

tid = (long)threadid;行でPrintHelloを実行しているスレッドの実行を中止するという単純なデバッグの目的を達成するのを手伝ってください。

答えて

0

結局、問題はあまりありませんでした。誰でも同様の問題がある場合はここでの手順は、以下のとおりです。gcc -ggdb main.c -o main -lpthread

  1. コンパイルして、Emacsで、gdb main
  2. 実行デバッガまたは(はい、それは-ggdbなく-gが、違いを作るように見えます) M-x gdb(およびコマンドgdb -i=mi main)ここで絶大な重要
    • :Emacsは、デフォルトではそれがノンストップモードでGDBを実行しようとする意味変数gdb-non-stop-settingset to tを持っています。ドキュメントによると、これは私が望むものではありません - 私は全停止モードを望みます。したがって、set-variableを実行するか、(setq gdb-non-stop-setting nil)を初期化ファイルに入れます(例:~/.emacs.d/init.el)。これが一度だけ行われると、Emacsの中からM-x gdbを起動してください...
  3. (gdb) b 9プログラムを実行するために、9
  4. (gdb) r行目にブレークポイントを設定します。いずれかのスレッドが9行目に達すると、実行が停止します。つまり、tid = (long)threadid;です。他のすべてのスレッドも停止します!完璧!
  5. (gdb) c他のスレッドが9行目に達すると実行が停止します。
  6. 何でもやって、今すぐ行動しています:
関連する問題