1. 程式人生 > >【linux】Valgrind工具集詳解(十三):DRD(執行緒錯誤檢測器)

【linux】Valgrind工具集詳解(十三):DRD(執行緒錯誤檢測器)

一、概述

多執行緒程式設計需要注意的問題:
資料競爭;鎖競爭;POSIX執行緒API使用不當;死鎖;

二、使用

1、例子main.c原始碼
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>

static pthread_mutex_t g_lock1;

int main()
{
	pthread_mutex_init(&g_lock1, NULL);

	pthread_mutex_unlock
(&g_lock1); pthread_mutex_lock(&g_lock1); printf("hello\n"); pthread_mutex_unlock(&g_lock1); pthread_mutex_destroy(&g_lock1); return 0; }
2、編譯
gcc -g main.c -pthread
3、檢測命令
valgrind --tool=drd ./a.out
4、輸出資訊
$ valgrind --tool=drd ./a.out
==5709== drd, a thread error detector
==5709== Copyright (C) 2006-2013, and GNU GPL'd, by Bart Van Assche.
==5709== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==5709== Command: ./a.out
==5709== 
==5709== Mutex not locked: mutex 0x601080, recursion count 0, owner 0.
==5709==    at 0x4C34FE3: pthread_mutex_unlock_intercept (drd_pthread_intercepts.c:692)
==5709==    by 0x4C34FE3: pthread_mutex_unlock (drd_pthread_intercepts.c:700)
==5709==    by 0x400769: main (main.c:12)
==5709== mutex 0x601080 was first observed at:
==5709==    at 0x4C338F6: pthread_mutex_init_intercept (drd_pthread_intercepts.c:603)
==5709==    by 0x4C338F6: pthread_mutex_init (drd_pthread_intercepts.c:612)
==5709==    by 0x40075F: main (main.c:10)
==5709== 
hello
==5709== 
==5709== For counts of detected and suppressed errors, rerun with: -v
==5709== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
5、DRD命令列選項詳解

–check-stack-var=<yes|no> [default: no]
設定DRD是否檢測棧上的資料競爭,預設情況下禁用。

–exclusive-threshold= [default: off]
設定互斥鎖和寫鎖的保持時間(以毫秒為單位),超時則列印錯誤訊息。此選項可以檢測鎖競爭。

–join-list-vol= [default: 10]
設定儲存訪問記憶體資訊的執行緒數量。

–first-race-only=<yes|no> [default: no]
設定只儲存第一次資料競爭資訊還是所有的。

–free-is-write=<yes|no> [default: no]
設定是否報告釋放鎖和寫鎖時的競爭。

–report-signal-unlocked=<yes|no> [default: yes]
設定是否報告在傳送訊號時沒有鎖定

–segment-merging=<yes|no> [default: yes]
控制段合併。段合併是一種限制資料競爭檢測演算法的記憶體,禁用時可能觸發記憶體不足錯誤。

–segment-merging-interval= [default: 10]
僅在建立了指定數量的新段後才執行段合併。

–shared-threshold= [default: off]
如果共享記憶體鎖定的持續時間超過指定時間(以毫秒為單位),則列印錯誤訊息。此選項可以檢測鎖競爭。

–show-confl-seg=<yes|no> [default: yes]
是否列印詳細內容。由於此資訊有助於查詢資料競爭的原因,因此預設情況下會啟用此選項。禁用此選項可使DRD的輸出更緊湊。

–show-stack-usage=<yes|no> [default: no]
線上程退出時列印棧記憶體使用情況。當程式建立大量執行緒時,限制為執行緒棧記憶體分配的虛擬記憶體量變得很重要。此選項可以觀察客戶端程式的每個執行緒使用了多少棧記憶體。

–ignore-thread-creation=<yes|no> [default: no]
設定是否應忽略執行緒建立期間的所有活動。

以下選項可用於監視客戶端程式的行為:

–trace-addr=<address> [default: none]
跟蹤指定地址的所有載入和儲存活動。可以多次指定此選項。

–ptrace-addr=<address> [default: none]
跟蹤指定地址的所有載入和儲存活動,並在釋放和重新分配該地址的記憶體後繼續執行此操作。

–trace-alloc=<yes|no> [default: no]
跟蹤所有記憶體分配和解除分配。可能會產生大量的輸出。

–trace-barrier=<yes|no> [default: no]
追蹤所有barrier活動。

–trace-cond=<yes|no> [default: no]
跟蹤所有條件變數活動。

–trace-fork-join=<yes|no> [default: no]
跟蹤所有執行緒建立和所有執行緒終止事件。

–trace-hb=<yes|no> [default: no]
跟蹤的執行ANNOTATE_HAPPENS_BEFORE(), ANNOTATE_HAPPENS_AFTER()以及 ANNOTATE_HAPPENS_DONE()客戶端請求。

–trace-mutex=<yes|no> [default: no]
跟蹤所有互斥活動。

–trace-rwlock=<yes|no> [default: no]
跟蹤所有讀寫器鎖定活動。

–trace-semaphore=<yes|no> [default: no]
跟蹤所有訊號量活動。