owned this note changed 6 years ago
Linked with GitHub

ThreadSanitizer: 運作原理分析與原始碼導讀 - 王琮瑋

由於場地問題,第二天我們移動到另一棟大樓啦!議程教室變動請見網站上的議程表

歡迎來到 https://hackmd.io/@coscup/2019 共筆

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

點擊本頁上方的 開始用 Markdown 一起寫筆記!
手機版請點選上方 按鈕展開議程列表。

請從這裡開始

What's data race?

Sync across threads

跨 Threads 執行時,誰先誰後?

Memory Model

  • Define which operation will create happens before realtion across threads

透過不同語言的 memory model 可以看出先後順序的關係

How threadSanitizer works?

  • Compile time - Compiler instrumentation
    • Memory access (r/w)
    • Sync operations (acquire/release)
    • Functions (entry/exit)
  • Runtime - detecion
    • Monitor all across thread memory events
    • For each 8-byte memory address , record old access events
    • Compare new access events with all old events to detect race
  • Runtime - report
    • maintain perthread
    • ge
##compile instrumentation
void foo(int *p)
`{
*p=42;
}
void foo(int *p)
{
 _tsan_fun_entry
}

Shadow State - one for every 8-byte memory

  • Composed by N 64-bit shadow words
  • Shadow word
    • ~ 13 bits : Thread ID
    • ~42 bits : Scalar Clock (Maintained by each Thread seperately )
    • 1 bit : IsWrite
    • 2 bits Access size (1/2/4/8)
    • 3 bits

How to detect

  • Compare new events with OLD events
  • New or OLD must be write
  • New and OLD must overlap
  • New and OLD are not synced
    • New not happens before old
    • OLD not happens before new

Compare based on local clock

  • How to compare

    • OLD( Thread B , clock 1000)
    • NEW( Thread A , clock 2000)
  • For each thread , maintain a clock vector for all other threads

  • For each sync variable , maintain

code related to clock

  • tsan_clock.cpp#L23
  • ThreadClock (clock vector for each Thread )
  • SyncClock (clock vector for eacch Sync Variable)
void ThreadClock::acquire(const SyncClock *src)
{ for(inti=0;i<kMaxThreads;i++)
    clock[1]=max(clock[i],src->clock[1]);}
void ThreadClock::()

Example 1

  • (T1 , Write , 0) -> (T2 , Read , 0)

Example 2

  • (T1 , LOck[M1] , 0) -> (T1 , Write , 1) -> (T1 , Unlock [M1] , 2 ) -> (T2 , LOCK[M1] , 0 )

Why 42 bits local clock ?

  • Why not increment over sync operation?
  • What kinds of report is useful
  • How to recover stack trace
    • Maintain a cyclic event list
    • Find the position of OLD operation

Q & A

tags: COSCUP2019 系統軟體社群議程 IB201
Select a repo