日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 單片機 > 程序喵大人

項目背景

現(xiàn)實困境

做C、C++開發(fā)的朋友應該都知道,C、C++中的內存是手動管理的,手動內存管理是一把雙刃劍,雖然提供了極致性能,但可能由于開發(fā)者的一點點疏忽,就導致內存泄露。據(jù)非官方統(tǒng)計,全球每年因內存泄露導致的系統(tǒng)崩潰事故超過120萬次。

C、C++開發(fā)者面臨以下痛點時經(jīng)常束手無策:

  • 幽靈式內存泄露:程序運行數(shù)天后,出現(xiàn)內存耗盡,因為程序是一點點釋放的,不太容易發(fā)現(xiàn)具體問題所在。
  • 多線程競態(tài)問題:死鎖導致的服務假死,并且不好復現(xiàn)。

現(xiàn)有方案的局限

傳統(tǒng)工具,Asanvalgrind、gdb功能非常強大,可以檢測基本的問題,但也恰恰是因為功能太過豐富且強大,所以性能損耗非常高,無法用于線上環(huán)境,并且難以捕獲隨機出現(xiàn)的死鎖場景。

項目目標

開發(fā)一個零侵入、高性能、全維度的運行時診斷系統(tǒng):

  • 內存監(jiān)控:可以實時追蹤每個內存塊的完整生命周期。
  • 死鎖檢測:可以檢測出死鎖,并能檢測出哪個線程的哪幾把鎖出現(xiàn)了死鎖,哪個線程由于等待的哪把鎖而出現(xiàn)的死鎖,可以精確關聯(lián)源代碼位置。
  • 內存泄露檢測:可以檢測出具體哪塊內存出現(xiàn)了泄露,并精確關聯(lián)到源代碼位置。

項目介紹

整體架構如圖:

內存檢測

直接看代碼,下面代碼會發(fā)生內存泄露:

extern "C"int TestMemoryLeak() {  int *ptr = (int *)malloc(100);  printf("TestMemoryLeak: %p\n", ptr);  free(ptr);  return 0; }  extern"C"int TestMemoryLeak2() {  int *ptr = (int *)malloc(110);  printf("TestMemoryLeak2: %p\n", ptr);  int *p = newint[10];   auto q = std::make_unique<int>(10);  return 0; } 

集成了工具后:

int main() {  OpenDynamicExample();  MemoryDetector detect("/mnt/d/project/camping/detector/libdynamic_example.so");   detect.StartTracking();   UseDynamicExample();   detect.StopTracking(); // 會打印 lib1.so 的內存使用情況  CloseDynamicExample();   return 0; } 

直接就可以檢測這個動態(tài)庫的內存情況:

本工具可以檢測出程序申請了多少內存,申請了多少塊內存,以及具體哪里發(fā)生了內存泄露,可以精確到具體的源代碼位置。

它不僅可以檢測malloc、free申請和釋放的內存,即便是C++的new、deletenew[]、delete[]、std::make_unique、std::make_shared,也可以,不管程序是通過哪種方式申請和釋放的內存,只要發(fā)生了內存泄露,工具都可以檢測到。

整體采用Hook方案,基本流程如圖:

死鎖檢測

看這段發(fā)生死鎖的代碼:

static void *ThreadFunc1(void *) {  pthread_mutex_lock(&mutexA);  std::cout << "Thread 1: Locked A\n";  sleep(1);   std::cout << "Thread 1: Trying to lock B\n";  pthread_mutex_lock(&mutexB);  std::cout << "Thread 1: Locked B\n";   pthread_mutex_unlock(&mutexB);  pthread_mutex_unlock(&mutexA);  return nullptr; }  static void *ThreadFunc2(void *) {  pthread_mutex_lock(&mutexB);  std::cout << "Thread 2: Locked B\n";  sleep(1);   std::cout << "Thread 2: Trying to lock A\n";  pthread_mutex_lock(&mutexA);  std::cout << "Thread 2: Locked A\n";   pthread_mutex_unlock(&mutexA);  pthread_mutex_unlock(&mutexB);  return nullptr; }  static void *ThreadFunc3(void *) {  std::mutex mtx;  std::cout << "Thread 3: Trying to lock mutex\n";  mtx.lock();  std::cout << "Thread 3: Locked mutex\n";  sleep(1);  mtx.unlock();  return nullptr; }  // 導出的函數(shù),用于創(chuàng)建死鎖場景 static void CreateDeadlock() {  pthread_t t1, t2, t3;  pthread_attr_t attr;   // 初始化線程屬性  pthread_attr_init(&attr);  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   // 創(chuàng)建分離的線程  pthread_create(&t1, &attr, ThreadFunc1, nullptr);  pthread_create(&t2, &attr, ThreadFunc2, nullptr);  pthread_create(&t3, &attr, ThreadFunc3, nullptr);   // 銷毀線程屬性  pthread_attr_destroy(&attr);   // 等待一段時間讓死鎖發(fā)生  sleep(3); } 

從代碼中可以看到,Thread1Thread2會發(fā)生死鎖,集成工具后:

LockHook lock_hook("./libdynamic_example.so"); if (!lock_hook.StartTracking()) {  std::cerr << "Failed to start lock tracking\n";  dlclose(handle);  return 1; } lock_hook.StopTracking(); 

結果如圖:

工具可以檢測出哪里發(fā)生了死鎖、哪個線程持有了哪把鎖、以及哪把鎖被哪個線程持有了。

且無論你是通過pthread_lock、還是mutex.lock、還是unique_lock或者lock_guard,只要發(fā)生了死鎖,工具都可以檢測到,并且可以定位到源代碼位置。

整體也采用Hook方案,流程如圖所示:

項目收獲

項目代碼量不大,核心代碼大概2000行左右,但涉及到的技術內容非常豐富且硬核。

通過本項目,你可以收獲到:

  1. 提升C、C++的編碼能力、內存管理黑科技、多線程調試技巧
  2. ELF 文件結構,包括section 和 segment的概念以及具體作用等。
  3. 編譯鏈接技術,動態(tài)鏈接與靜態(tài)鏈接的區(qū)別。
  4. 動態(tài)鏈接與加載,了解動態(tài)鏈接器如何在運行時解析符號和加載動態(tài)庫。
  5. PLT機制,與GOT之間的關系。
  6. GOT作用,如何存儲動態(tài)鏈接的函數(shù)地址。
  7. 函數(shù)調用約定,不同架構下的函數(shù)調用約定。
  8. 內存保護機制,了解Linux上的內存保護機制(如DEP、ASLR),以及如何影響代碼注入和鉤子技術。
  9. 調試工具,使用工具(如objdump、gdb)分析二進制文件,理解如何定位和修改PLT。
  10. Hook技術,如何將自定義代碼注入到目標進程中,以實現(xiàn)鉤子功能。
  11. 鉤子的安全性,鉤子技術是否有風險。
  12. 編寫和測試,學習如何編寫鉤子代碼,并在不同環(huán)境中進行測試。
  13. 鉤子技術的性能分析。
  14. 動態(tài)庫的加載過程,詳細了解共享庫的加載過程,包括如何在運行時解析依賴關系。
  15. 符號解析與重定位,符號解析的機制以及重定位表的作用。
  16. 內存管理和分配機制,內存管理機制,特別是如何安全地分配和修改內存以實現(xiàn)鉤子。
  17. 內存泄漏檢測技術,理解了內存管理分配機制,可以實現(xiàn)檢測內存泄漏的能力。
  18. 鎖機制,鎖的底層實現(xiàn)原理,如何實現(xiàn)加解鎖相關的鉤子。
  19. 死鎖檢測技術,理解了加解鎖的底層機制,可以實現(xiàn)檢測程序是否產(chǎn)生了死鎖。
  20. 編譯鏈接技術,Debug模式和Release模式的區(qū)別。
  21. 符號管理機制,調試符號信息的作用。
  22. 調用棧技術,如何獲取線程的調用堆棧,如何根據(jù)地址解析出對應代碼函數(shù)名和行號。


本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
關閉