Linux应用程序获取线程栈的信息

一. 参考网址

  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 = %d, avail = %d, total = %d***\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`函数获取栈的大小和地址。然后,我们使用汇编语言的方式获取当前栈指针位置,从而计算已使用的栈空间大小。最后,我们计算剩余的栈空间大小并打印所有的栈信息。

 

  

posted @ 2024-04-22 14:44  shanyu20  阅读(17)  评论(0编辑  收藏  举报