Zircon 程式碼利用 clang 的執行緒安全分析功能來 並透過機器驗證部分同步處理的不變體。這些 建構 Clang 時,會檢查註解 (請參閱 入門,瞭解建構應用程式的操作說明 clang)。
使用方法
在 Zircon 中,我們提供一組用來包裝註解的巨集,
為同步基元加上註解。編寫與下列項目相關的新程式碼時
同步處理或為現有程式碼加上註解,因此在大部分的情況下,您應使用
執行緒註解巨集
<lib/zircon-internal/thread_annotations.h.
這些巨集的開頭為 "TA_"
是為了進行執行緒分析。最常出現
常用的功能包括:
TA_GUARDED(x)
:有功能 (例如鎖定) 會保護加註的變數x
TA_ACQ(x...)
函式會取得x
組合中的所有互斥鎖,並在傳回後保留這些互斥鎖TA_REL(x...)
函式會釋放x
集合中的所有互斥鎖TA_REQ(x...)
函式會要求呼叫端使用x
組合中的所有互斥鎖TA_EXCL(x...)
函式會規定呼叫端不得持有x
組合中的任何互斥鎖
舉例來說,類別包含受保護成員變數 'int foo_'
保護的類別
Mutex 的註解如下:
// example.h
class Example {
public:
// Public function has no locking requirements and thus needs no annotation.
int IncreaseFoo(int by);
private:
// This is an internal helper routine that can only be called with |lock_|
// held. Calling this without holding |lock_| is a compile-time error.
// Annotations like TA_REQ, TA_ACQ, TA_REL, etc are part of the function's
// interface and must be on the function declaration, usually in the header,
// not the definition.
int IncreaseFooLocked(int by) TA_REQ(lock_);
// This internal routine requires that both |lock_| and |foo_lock_| be held by the
// caller.
int IncreaseFooAndBarLocked(int foo_by, int bar_by) TA_REQ(lock_) TA_REQ(bar_lock_);
// The TA_GUARDED(lock_) annotation on |foo_| means that |lock_| must be
// held to read or write from |foo_|.
int foo_ TA_GUARDED(lock_);
// |lock_| can be declared after annotations referencing it,
// if desired.
Mutex lock_;
Mutex bar_lock_;
};
// example.cpp
int Example::IncreaseFoo(int by) {
int new_value;
{
AutoLock lock(&lock_); // fbl::AutoLock is annotated
new_value = IncreaseFooLocked(by);
}
return new_value;
}
請注意,如果註解允許一組互斥物件, 多次套用註解,或為 註解。換句話說,以下兩個宣告是相等的。
int IncreaseFooAndBarLocked(int foo_by, int bar_by) TA_REQ(lock_) TA_REQ(bar_lock_);
int IncreaseFooAndBarLocked(int foo_by, int bar_by) TA_REQ(lock_, bar_lock_);
透過 sysroot 公開的程式庫程式碼必須使用更奇怪的名稱 巨集是由 Google 提供的 system/public/zircon/compiler.h 避免與 sysroot 的消費者發生衝突。
最佳做法
註解必須與註解和 ID 相輔相成,以利程式碼 容易理解註解不會取代註解或清除名稱。請嘗試 編寫與鎖定相關的程式碼時,請遵循下列最佳做法:
受鎖定功能保護的群組成員變數。運作位置 除了用註解來記錄受保護的內容之外 註解。例如,當多個成員變數受一個鎖定保護時 多個鎖定分別受到不同的鎖定方式保護 因此,相較於其他鎖定方式 逐一介紹各個註解
為需要鎖定的函式命名,並加上「Locked()」尾碼。如果有 為呼叫函式可能顯示的多個鎖定類型 確保函式名稱中的選項撥打電話時應留意的讀者 你將無法看到註解
限制
執行緒安全分析是在編譯期間執行純靜態的檢查
無法理解有條件的鎖定或跨越區域的鎖定模式
編譯單元,以無法透過靜態註解表示。在許多
這項分析還是相當實用,但有些情況下
也無法理解停用分析的主要跳脫框架
是在函式定義中加入註解 TA_NO_THREAD_SAFETY_ANALYSIS
容易造成混淆其他逸出機制包括
也可使用,詳情請參閱 Clang 說明文件。情境
人類可能難以理解
以及機器,此時應附有註解指出
執行緒安全分析可透過許多方式破解,例如
如使用指標舉例來說,當您取得受到保護資料的地址時
成員 Clang 未追蹤警衛,例如受 Lock 保護的 foo_
在不按住鎖頭的情況下,系統不會記錄到 memset(&foo_, 0, sizeof(foo_))
的通話
違反 YouTube 政策。