iis服务器助手广告广告
返回顶部
首页 > 资讯 > 操作系统 >Linux中堆栈的示例分析
  • 525
分享到

Linux中堆栈的示例分析

2023-06-16 12:06:50 525人浏览 独家记忆
摘要

这篇文章给大家分享的是有关linux中堆栈的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。用下面的程序作为例子:void a() {    &n

这篇文章给大家分享的是有关linux中堆栈的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

用下面的程序作为例子:

void a() {     //stopped here } void b() {      a(); } void c() {      a(); } int main() {     b();     c(); }

如果调试器停在 //stopped here'  这行,那么有两种方法可以达到:main->b->a或main->c->a`。如果我们用 LLDB  设置一个断点,继续执行并请求一个回溯,那么我们将得到以下内容:

* frame #0: 0x00000000004004da a.out`a() + 4 at bt.cpp:3   frame #1: 0x00000000004004e6 a.out`b() + 9 at bt.cpp:6   frame #2: 0x00000000004004fe a.out`main + 9 at bt.cpp:14   frame #3: 0x00007ffff7a2e830 libc.so.6`__libc_start_main + 240 at libc-start.c:291   frame #4: 0x0000000000400409 a.out`_start + 41

这说明我们目前在函数 a 中,a 从函数 b 中跳转,b 从 main 中跳转等等。***两个帧是编译器如何引导 main 函数的。

现在的问题是我们如何在 x86_64 上实现。最稳健的方法是解析 ELF 文件的 .eh_frame  部分,并解决如何从那里展开堆栈,但这会很痛苦。你可以使用 libunwind  或类似的来做,但这很无聊。相反,我们假设编译器以某种方式设置了堆栈,我们将手动遍历它。为了做到这一点,我们首先需要了解堆栈的布局。

    High |   ...   | +---------+ |  Arg 1  | +---------+ |  Arg 2  | +---------+ | Return  | +---------+ |Saved EBP| +---------+ |  Var 1  | +---------+ |  Var 2  | +---------+ |   ...   |     Low

如你所见,***一个堆栈帧的帧指针存储在当前堆栈帧的开始处,创建一个链接的指针列表。堆栈依据这个链表解开。我们可以通过查找 DWARF  信息中的返回地址来找出列表中下一帧的函数。一些编译器将忽略跟踪 EBP 的帧基址,因为这可以表示为 ESP  的偏移量,并可以释放一个额外的寄存器。即使启用了优化,传递 -fno-omit-frame-pointer 到 GCC 或 Clang  会强制它遵循我们依赖的约定。

我们将在 print_backtrace 函数中完成所有的工作:

void debugger::print_backtrace() {

首先要决定的是使用什么格式打印出帧信息。我用了一个 lambda 来推出这个方法:

auto output_frame = [frame_number = 0] (auto&& func) mutable {     std::cout << "frame #" << frame_number++ << ": 0x" << dwarf::at_low_pc(func)               << ' ' << dwarf::at_name(func) << std::endl; };

打印输出的***帧是当前正在执行的帧。我们可以通过查找 DWARF 中的当前程序计数器来获取此帧的信息:

auto current_func = get_function_from_pc(get_pc());     output_frame(current_func);

接下来我们需要获取当前函数的帧指针和返回地址。帧指针存储在 rbp 寄存器中,返回地址是从帧指针堆栈起的 8 字节。

auto frame_pointer = get_reGISter_value(m_pid, reg::rbp); auto return_address = read_memory(frame_pointer+8);

现在我们拥有了展开堆栈所需的所有信息。我只需要继续展开,直到调试器*** main,但是当帧指针为 0x0 时,你也可以选择停止,这些是你在调用 main  函数之前调用的函数。我们将从每帧抓取帧指针和返回地址,并打印出信息。

while (dwarf::at_name(current_func) != "main") {         current_func = get_function_from_pc(return_address);         output_frame(current_func);         frame_pointer = read_memory(frame_pointer);         return_address = read_memory(frame_pointer+8);     } }

就是这样!以下是整个函数:

void debugger::print_backtrace() {     auto output_frame = [frame_number = 0] (auto&& func) mutable {         std::cout << "frame #" << frame_number++ << ": 0x" << dwarf::at_low_pc(func)                   << ' ' << dwarf::at_name(func) << std::endl;     };     auto current_func = get_function_from_pc(get_pc());     output_frame(current_func);     auto frame_pointer = get_register_value(m_pid, reg::rbp);     auto return_address = read_memory(frame_pointer+8);     while (dwarf::at_name(current_func) != "main") {         current_func = get_function_from_pc(return_address);         output_frame(current_func);         frame_pointer = read_memory(frame_pointer);         return_address = read_memory(frame_pointer+8);     } }

添加命令

当然,我们必须向用户公开这个命令。

else if(is_prefix(command, "backtrace")) {     print_backtrace(); }

感谢各位的阅读!关于“Linux中堆栈的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: Linux中堆栈的示例分析

本文链接: https://www.lsjlt.com/news/283646.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Linux中堆栈的示例分析
    这篇文章给大家分享的是有关Linux中堆栈的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。用下面的程序作为例子:void a() {    &n...
    99+
    2023-06-16
  • JavaScript中堆栈与拷贝的示例分析
    小编给大家分享一下JavaScript中堆栈与拷贝的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一.堆栈的定义栈是一种特殊的线性表。其特殊性在于限定插入...
    99+
    2023-06-15
  • Java堆栈内存、堆外内存、零拷贝的示例分析
    这篇文章将为大家详细讲解有关Java堆栈内存、堆外内存、零拷贝的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、堆栈内存堆栈内存,顾名思义,指的是堆内存以及栈内存,其中,堆内存是由Java GC...
    99+
    2023-06-15
  • Javascript中的堆、栈操作示例
    这篇文章将为大家详细讲解有关Javascript中的堆、栈操作示例,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。堆、栈都是一种数据项按序排列的数据结构,它涉及到数据在内存中的存储方式,Javascript...
    99+
    2023-06-14
  • Linux TCP/IP协议栈的示例分析
    这篇文章将为大家详细讲解有关Linux TCP/IP协议栈的示例分析,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。TCP特点我们都非常清楚TCP协议设计的初衷,就是保证数据传输的快速,有序,...
    99+
    2023-06-05
  • web中堆排序的示例分析
    这篇文章给大家分享的是有关web中堆排序的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种**选择排序,**它的最坏,最好,平均时间复杂度均为O(...
    99+
    2023-06-27
  • Node中堆内存分配的示例分析
    这篇文章将为大家详细讲解有关Node中堆内存分配的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。V8 垃圾回收简介首先,简单介绍一下V8垃圾回收器。内存的存储分配...
    99+
    2024-04-02
  • Golang编程中堆与栈的异同分析
    堆与栈是计算机内存中两种常见的数据存储方式,它们在Golang编程中起着重要的作用。本文将从概念、特点、存储结构以及使用方面对堆与栈进行详细的比较分析,并结合具体的Golang代码示例...
    99+
    2024-03-13
    golang
  • C++函数栈帧的示例分析
    这篇文章将为大家详细讲解有关C++函数栈帧的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、什么是函数栈帧每一次函数调用都是一个过程,为函数开辟栈空间,用于本次函数调用中临时变量的保存、现场保护...
    99+
    2023-06-20
  • linux中make的示例分析
    小编给大家分享一下linux中make的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!规则规则rule是指示 make 应该如何并且何时构建一个被称作为目...
    99+
    2023-06-16
  • JavaScript中数组、栈与队列的示例分析
    这篇文章主要介绍了JavaScript中数组、栈与队列的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。...
    99+
    2024-04-02
  • linux中iostat的示例分析
    这篇文章主要介绍linux中iostat的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!iostat主要用于报告中央处理器(CPU)统计信息和整个系统、适配器、tty 设备、磁盘和 CD-ROM 的输入/输出...
    99+
    2023-06-12
  • Linux中Base64的示例分析
    这篇文章主要为大家展示了“Linux中Base64的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Linux中Base64的示例分析”这篇文章吧。Base64编码在电子邮件中很常见,Fo...
    99+
    2023-06-27
  • python数据结构堆的示例分析
    小编给大家分享一下python数据结构堆的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!1、说明堆是用数据结构来实现的一种算法:树,数组均可。堆本身是一棵完全二叉树。2、特点最大堆:所有父节点的值大于子节点的值最小...
    99+
    2023-06-15
  • JS中数据结构之栈的示例分析
    这篇文章给大家分享的是有关JS中数据结构之栈的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。栈是一种高效的数据结构,因为数据只能在栈顶添加或删除,所以这样的操作很快,而且...
    99+
    2024-04-02
  • Python中栈举例分析
    本篇内容主要讲解“Python中栈举例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python中栈举例分析”吧!1、问题描述Python中数据类型有列表,元组,字典,队列,栈,树等等。像列...
    99+
    2023-06-25
  • 如何浅析C++中的C++堆栈
    这篇文章给大家介绍如何浅析C++中的C++堆栈,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。想要学好C++的C++堆栈,那么就要了解什么是C++堆栈,所为C++堆栈就是一种数据项按序排列的数据结构,只能在一端(称为栈顶...
    99+
    2023-06-17
  • Linux中日志的示例分析
    这篇文章主要介绍Linux中日志的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!日志的三种类型#内核及系统日志:这种日志数据由系统服务rsyslog统一管理,根据其主配置文件/etc/rsyslog.conf...
    99+
    2023-06-27
  • C++中堆和栈问题的分析与解决方案
    C++中堆和栈问题的分析与解决方案在C++编程中,堆和栈是两种常用的内存管理方式。堆用于动态分配内存,而栈则用于存储局部变量和函数调用的上下文信息。然而,错误的使用堆和栈可能导致内存泄漏、段错误和无法预料的行为。因此,在编写C++代码时需要...
    99+
    2023-10-22
    内存管理 (Memory management) 栈溢出 (Stack Overflow) 堆分配 (Heap allo
  • Java中堆的向下和向上调整示例分析
    这篇文章主要介绍Java中堆的向下和向上调整示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、关于堆JDK1.8中的PriortyQueue(优先级队列)底层使用了堆的数据结构,而堆实际就是在完全二叉树的基础...
    99+
    2023-06-25
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作