一. 參考網址
1. Linux應用程式設計:用一種討巧方式,來獲取執行緒棧的使用資訊
2. chatGPT的輸出
二. 程式碼實戰
1. 適用於ARM的彙編程式碼
1 #define _GNU_SOURCE //沒有此句話,則編譯會出錯 2 3 #include <stdio.h> 4 #include <string.h> 5 #include <pthread.h> 6 #include <unistd.h> 7 #include <sys/resource.h> 8 9 typedef char s8; 10 typedef unsigned char u8; 11 typedef int s32; 12 13 s32 PrintThreadStackInfo(s8 *comment) 14 { 15 size_t used, avail; 16 pthread_attr_t attr; 17 void *stack_addr; 18 size_t stack_size; 19 size_t esp_val; // 獲取棧暫存器 ESP 的當前值 20 21 #if 0 22 asm("movl %%esp, %0" : "=m"(esp_val) :); //X86彙編 23 #else 24 asm volatile ("mov %0, sp\n" : "=r" (esp_val)); //Arm彙編 25 #endif 26 // 透過執行緒屬性,獲取棧區的起始地址和空間總大小 27 memset(&attr, 0, sizeof(pthread_attr_t)); 28 pthread_getattr_np(pthread_self(), &attr); 29 pthread_attr_getstack(&attr, &stack_addr, &stack_size); 30 pthread_attr_destroy(&attr); 31 avail = esp_val - (size_t)stack_addr; 32 used = stack_size - avail; 33 34 if (comment) 35 printf(comment); 36 printf("espVal = 0x%x \n", esp_val); 37 printf("statck top = %p \n", stack_addr); 38 printf("stack bottom = %p \n", stack_addr + stack_size); 39 printf("***stack info: used = %ld, avail = %ld, total = %lu***\n", 40 used, avail, stack_size); 41 42 return SUCCESS; 43 }
2. 編譯註意事項
1)函式:pthread_getattr_np
3. chatGPT輸出
對不起,我的錯誤。你可以使用`pthread_getattr_np`函式和`pthread_attr_getstack`函式來獲取當前執行緒的棧資訊。這裡是一個修改後的示例程式碼: ```c #include <stdio.h> #include <pthread.h> #include <unistd.h> // 獲取棧資訊的函式 void print_stack_info() { pthread_attr_t attr; size_t stack_size; void *stack_addr; // 初始化attr物件 pthread_getattr_np(pthread_self(), &attr); // 獲取棧大小和棧地址 pthread_attr_getstack(&attr, &stack_addr, &stack_size); // 計算已使用的棧空間大小 unsigned long current_sp; asm volatile ("mov %0, sp\n" : "=r" (current_sp)); long used_stack_size = (char*)stack_addr + stack_size - (char*)current_sp; // 計算剩餘的棧空間大小 long free_stack_size = stack_size - used_stack_size; // 列印棧資訊 printf("Stack Address: %p\n", stack_addr); printf("Stack Size: %lu bytes\n", stack_size); printf("Used Stack Size: %ld bytes\n", used_stack_size); printf("Free Stack Size: %ld bytes\n", free_stack_size); // 銷燬attr物件 pthread_attr_destroy(&attr); } int main() { // 建立一個執行緒,並在其中呼叫print_stack_info函式 pthread_t thread; pthread_create(&thread, NULL, (void *)print_stack_info, NULL); pthread_join(thread, NULL); return 0; } ``` 在這個修改後的示例程式碼中,我們使用`pthread_getattr_np`函式獲取當前執行緒的屬性,並使用`pthread_attr_getstack`函式獲取棧的大小和地址。然後,我們使用匯編語言的方式獲取當前棧指標位置,從而計算已使用的棧空間大小。最後,我們計算剩餘的棧空間大小並列印所有的棧資訊。