0

-finstrument-functionsは、各関数呼び出しの入力および終了情報を生成し、ドットを使用して上記のように描画していました。ただし、1 つの問題が見つかりました。私のmain関数では、2 つのスレッドを作成します。1 つは driver_TASL と呼ばれ、もう 1 つは keyBoard_TASK です。しかし、私の生成された画像では、私keyBoard_TASKは によって呼び出されたようdriver_TASKです。によって呼び出されるこれらの 2 つの TASK のようにする必要があります。main

備考:写真をアップロードできないので、以下に説明します。

関数呼び出しを生成すると、次のようになります。

  • main電話driver_TASK
  • main電話keyBoard_TASK

ただし、

  • main電話driver_TASK
  • driver_TASK電話keyboard_TASK

keyBoard_TASKが によって呼び出されたのはなぜdriver_TASKですか? mainそれは私が思うに呼び出されるべきです

ソース コードでは、次のように記述しました (コード内のいくつかの印刷関数を削除しました)。

int main(/*@ unused @*/int argc, /*@ unused @*/char *argv[]) //comment for lint
{
    int         res;
    pthread_t   driver_thread, keyBoard_thread;
    void        *thread_result;

    res = pthread_create(&driver_thread, NULL, driver_TASK, (void *)&_gDriverStatus);
    if(res != 0)
    {
        perror("Thread Creation Failed");
        exit(EXIT_FAILURE);
    }

    sleep(1);

    res = pthread_create(&keyBoard_thread, NULL, keyBoard_TASK, (void *)&_gKeyStatus);
    if(res != 0)
    {
        perror("Thread Creation Failed");
        exit(EXIT_FAILURE);
    }

    res = pthread_join(driver_thread, &thread_result);
    if(res != 0)
    {
        perror("Thread Join Failed");
        exit(EXIT_FAILURE);
    }

    res = pthread_join(keyBoard_thread, &thread_result);
    if(res != 0)
    {
        perror("Thread Join Failed");
        exit(EXIT_FAILURE);
    }

    exit(EXIT_SUCCESS);
}

自動ドット ファイルも添付しました。関数呼び出しのフローチャートは pvtace によって自動的に生成されます。

digraph DEMO {

  main [shape=rectangle]
  driver_TASK [shape=rectangle]
  DDI_DRIVER_Probe [shape=rectangle]
  _Driver_Clear [shape=ellipse]
  _Driver [shape=ellipse]
  DRIVER_Probe_Demo [shape=ellipse]
  DDI_DRIVER_Init [shape=rectangle]
  DRIVER_Init_Demo [shape=rectangle]
  _DRIVER_Init_Demo [shape=ellipse]
  DDI_DRIVER_Running [shape=rectangle]
  DRIVER_Running_Demo [shape=rectangle]
  _DRIVER_Running_Demo [shape=ellipse]
  keyBoard_TASK [shape=rectangle]
  main -> DBG_PrintColor [label="2 calls" fontsize="10"]
  main -> driver_TASK [label="1 calls" fontsize="10"] //this is correct
  driver_TASK -> DBG_PrintColor [label="6 calls" fontsize="10"]
  driver_TASK -> DDI_DRIVER_Probe [label="1 calls" fontsize="10"]
  driver_TASK -> DDI_DRIVER_Init [label="1 calls" fontsize="10"]
  driver_TASK -> DDI_DRIVER_Running [label="1 calls" fontsize="10"]
  driver_TASK -> keyBoard_TASK [label="1 calls" fontsize="10"] //this is not correct
  DDI_DRIVER_Probe -> _Driver_Clear [label="1 calls" fontsize="10"]
  DDI_DRIVER_Probe -> _Driver [label="1 calls" fontsize="10"]
  DDI_DRIVER_Probe -> DRIVER_Probe_Demo [label="1 calls" fontsize="10"]
  DDI_DRIVER_Init -> _Driver [label="1 calls" fontsize="10"]
  DDI_DRIVER_Init -> DRIVER_Init_Demo [label="1 calls" fontsize="10"]
  DRIVER_Init_Demo -> _DRIVER_Init_Demo [label="1 calls" fontsize="10"]
  DDI_DRIVER_Running -> _Driver [label="1 calls" fontsize="10"]
  DDI_DRIVER_Running -> DRIVER_Running_Demo [label="1 calls" fontsize="10"]
  DRIVER_Running_Demo -> _DRIVER_Running_Demo [label="1 calls" fontsize="10"]
  keyBoard_TASK -> DBG_PrintColor [label="6 calls" fontsize="10"]

}
4

2 に答える 2

2

コール グラフ情報を収集するために「instrumental」ライブラリを使用していると仮定します(そうでない場合は、何を使用しているか、および/またはルーチンで何を行っているかを示す必要があります) __cyg_profile_func_enter()__cyg_profile_func_exit()

実装 ( http://www.suse.de/~krahmer/instrumental/で入手可能) を見ると、コール グラフ情報がスレッド セーフな方法で収集されていないことが明らかです。呼び出された各関数は、呼び出されたときにログ ファイルに記録され、コール グラフの深さはグローバル変数 (実際には静的変数) に保持されます。呼び出しチェーンに関する情報もグローバル配列に保持されます。

つまり、次の一連のイベントに沿って何かが発生します。

__cyg_profile_func_enter()  - for main() on main thread
__cyg_profile_func_enter()  - for driver_TASK() on driver_thread
__cyg_profile_func_enter()  - for keyBoard_TASK() on keyboard_thread

...

これらのイベントが、イベントを介在させることなく、この順序でたまたま発生するという事実は__cyg_profile_func_exit()、インストルメンタル ライブラリが次のように物事を記録することを意味します。

main()
|
+--- driver_TASK()
     |
     +--- keyBoard_TASK()

スレッドごとに個別の呼び出しグラフが必要な場合 (インストルメンテーションでスレッドを認識する必要があります)。この問題を解決するには、次のいずれかを行う必要があります。

  • スレッド対応の計測ライブラリを見つける
  • 現在使用しているものにスレッド認識を追加します
  • 生成されたログを手作業で修正します (スレッド関数が比較的単純な場合は単純かもしれませんが、大規模で複雑な作業になる可能性があります)。
于 2012-09-20T08:20:54.583 に答える
0

問題は、関数をどのように計測するかにあるはずです。厳密に言えば、mainこれらの関数のいずれも呼び出していません。スレッドの起動は、関数呼び出しと同等ではありません。どちらの関数も、呼び出し元としていくつかのシステム関数のみを表示する必要があります。mainコールスタックにありません。

これで、 と 2 つの関数の関係mainは特別な依存関係になり、どうにかして別の方法で追跡する必要があります。

于 2012-09-20T08:00:24.643 に答える