首页 > 系统相关 >Linux应用程序获取线程栈的信息

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

时间:2024-04-22 14:56:52浏览次数:25  
标签:printf addr attr pthread 应用程序 线程 Linux stack size

一. 参考网址

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

 

  

标签:printf,addr,attr,pthread,应用程序,线程,Linux,stack,size
From: https://www.cnblogs.com/shanyu20/p/18150624

相关文章

  • 线程池的运行逻辑与你想象的不一样,它是池族中的异类
    只要是web项目,程序都会直接或间接使用到线程池,它的使用是如此频繁,以至于像空气一样,大多数时候被我们无视了。但有时候,我们会相当然地认为线程池与其它对象池(如:数据库连接池)一样,要用的时候向池子索取,用完后归还给它即可。然后事实上,线程池独树一帜、鹤立鸡群,它与普通的对象池就是......
  • 面试必备,Linux面试题和答案!
    ​作为测试开发,对于Linux相关知识,不管是面试还是工作,多多少少你还是得会点。再说了,现在行情极差,要求又高,linux也是面试重头戏,所以,今天给你分享Linux相关面试题和答案。题目1、绝对路径用什么符号表示?当前目录、上层目录用什么表示?主目录用什么表示?切换目录用什么命令?2、怎......
  • 3568F-Linux系统启动卡制作及系统固化
     ......
  • Linux 替换cat
    mv/bin/cat /bin/cat_oln-s/usr/bin/coreutils/sbin/catnano /bin/cat#!/bin/bashfunctionCPUinfo{#在这里编写处理/proc/cpuinfo文件并输出结果的代码localcpuinfo_contentcpuinfo_content=$(</proc/cpuinfo)#将内容中的e660735d11e55937替换......
  • 20-Linux编程
    20.1编辑器的选择20.1.1Vim编辑器编辑和保存文件搜索字符串替换字符串:[range]s/pattern/string/[c,e,g,i]替换范围选项标志含义c每次替换前询问e不显示错误信息g替换一行中的所有匹配项(这个选项通常需要使用)i不区分大小写针对程序员的......
  • flutter 移动应用程序中打开URL
    url_launcher:^6.2.5 在Flutter中,url_launcher库是用于在移动应用程序中打开URL的常用工具。它允许你通过调用系统的浏览器或其他应用程序来打开指定的URL,比如网页链接、电子邮件链接、电话号码等。这个库提供了一种简单的方法来实现在应用中跳转到外部链接的功能,增强了应用的......
  • 在Linux中,文件系统是如何组织的?
    在Linux中,文件系统是一种层级结构,用来组织和存储文件的方式。其核心概念如下:目录结构:Linux文件系统采用的是树形层次结构,从单一的根目录/开始,所有的文件和目录都位于这一结构的不同分支下。根目录/是整个文件系统的起点,其中包含了多个标准目录,例如:/bin存储常用的基本......
  • 在Linux中,inode是什么?
    在Linux或类Unix文件系统中,inode(索引节点)是一个非常重要的数据结构,它用来存储文件或目录的元数据。inode并不包含文件名,而是记录了与文件或目录实体相关的一切重要信息,这些信息包括但不限于:文件大小(Size):指出文件占用的数据块总数。文件权限(Permissions):包括文件所有者、所属组以......
  • 在Linux中,/usr和/etc目录的用途有什么?
    在Linux操作系统中,/usr和/etc目录各有其明确的用途和重要性:1./usr目录:/usr目录是系统中用户程序和相关文件的主要存储位置,主要用于存放那些并非系统启动所必需的、但对于大多数或全部用户有用的数据。/usr目录下的结构划分细致,主要包括以下子目录:/usr/bin:存放用户和......
  • 在Linux中,常用的Linux命令。
    在Linux系统中,以下是一些非常基础且常用的命令,涵盖了文件和目录操作、系统状态查询、文本处理以及其他日常管理任务等方面:文件和目录操作:ls:列出目录内容,可以使用-l参数查看详细信息,-a参数显示隐藏文件。cd:切换目录,如cdDocuments或cd..回退到上一级目录。pwd:显示当......