打印出堆栈指针的值

2024-11-14 08:29:00
admin
原创
56
摘要:问题描述:如何在 Linux(Debian 和 Ubuntu)中用 C 打印出堆栈指针的当前值?我尝试过谷歌,但没有找到结果。解决方案 1:有一个技巧,但它不可移植,甚至不能保证能起作用,那就是简单地将本地地址作为指针打印出来。void print_stack_pointer() { void* p = ...

问题描述:

如何在 Linux(Debian 和 Ubuntu)中用 C 打印出堆栈指针的当前值?

我尝试过谷歌,但没有找到结果。


解决方案 1:

有一个技巧,但它不可移植,甚至不能保证能起作用,那就是简单地将本地地址作为指针打印出来。

void print_stack_pointer() {
  void* p = NULL;
  printf("%p", (void*)&p);
}

p这实际上会打印出当前堆栈指针的近似地址

解决方案 2:

没有可移植的方法可以做到这一点。

在 GNU C 中,这可能适用于具有名为 SP 的寄存器的目标 ISA,包括 x86,其中 gcc 将“SP”识别为 ESP 或 RSP 的缩写。

// broken with clang, but usually works with GCC
register void *sp asm ("sp");
printf("%p", sp);

GCC 现在已不推荐使用本地寄存器变量:

此功能唯一支持的用途是在调用扩展 asm时指定输入和输出操作数的寄存器

定义寄存器变量不会保留寄存器。除了调用扩展 asm 时,指定寄存器的内容无法保证。因此,明确不支持以下用途。如果它们似乎有效,那只是偶然事件,并且可能会由于周围代码中(看似)不相关的更改,甚至未来版本的 gcc 优化中的微小更改而停止按预期工作。...

在实践中,它也被 clang 破坏,sp像任何其他未初始化的变量一样被处理。

解决方案 3:

除了duedl0r关于GCC的具体回答之外,您还可以使用__builtin_frame_address(0)GCC 特定的(但不是x86特定的)。

这也应该适用于Clang(但它存在一些错误)。

采用本地地址(正如JaredPar 回答的那样)也是一个解决方案。

请注意,据我所知,C 标准理论上不需要任何调用堆栈。

记住 Appel 的论文:垃圾收集可以比堆栈分配更快;一个非常奇怪的 C 实现可以使用这种技术!但据我所知,它从未用于 C。

我们可以梦想其他技术。而且,你可以拆分堆栈(至少在最近的 GCC 上),在这种情况下,堆栈指针的概念就没有什么意义了(因为堆栈不是连续的,可能由许多段组成,每个段包含几个调用框架)。

解决方案 4:

Linux您可以使用伪文件系统proc来打印堆栈指针。

查看这里的/proc/your-pid/stat 伪文件,其中的字段2829

startstack %lu
堆栈的起始(即底部)地址。

kstkesp %lu
ESP(堆栈指针)的当前值,可以在进程的内核堆栈页中找到。

您只需解析这两个值!

解决方案 5:

您还可以使用扩展的汇编指令,例如:

#include <stdint.h>

uint64_t getsp( void )
{
    uint64_t sp;
    asm( "mov %%rsp, %0" : "=rm" ( sp ));
    return sp;
}

对于 32 位系统,必须将 64 替换为 32,并将 rsp 替换为 esp。

解决方案 6:

您可以使用 setjmp。具体细节取决于实现,请查看头文件。

#include <setjmp.h>
jmp_buf jmp;
setjmp(jmp);
printf("%08x
", jmp[0].j_esp);

在执行未知代码时,这也很方便。您可以检查前后的 sp 并执行longjmp清理。

解决方案 7:

如果您使用的是 msvc,则可以使用提供的函数_AddressOfReturnAddress()

它将返回返回地址的地址,该地址保证是函数入口处的 RSP 值。从该函数返回后,由于返回地址被弹出,RSP 值将增加 8。使用该信息,您可以编写一个简单的函数来返回堆栈指针的当前地址,如下所示:

uintptr_t GetStackPointer() {
    return (uintptr_t)_AddressOfReturnAddress() + 0x8;
}

int main(int argc, const char argv[]) {
    uintptr_t rsp = GetStackPointer();
    printf("Stack pointer: %p
", rsp);
}

展示

解决方案 8:

您可以在文件中找到该信息/proc/<your-process-id>/maps,与字符串出现的行相同[stack](因此它与编译器或机器无关)。这种方法的唯一缺点是,要读取该文件,需要 root 权限。

解决方案 9:

尝试 lldb 或 gdb。例如,我们可以在 lldb 中设置回溯格式。

settings set frame-format "frame #${frame.index}: ${ansi.fg.yellow}${frame.pc}: {pc:${frame.pc},fp:${frame.fp},sp:${frame.sp}}  ${ansi.normal}{ ${module.file.basename}{`${function.name-with-args}{${frame.no-debug}${function.pc-offset}}}}{ at ${ansi.fg.cyan}${line.file.basename}${ansi.normal}:${ansi.fg.yellow}${line.number}${ansi.normal}{:${ansi.fg.yellow}${line.column}${ansi.normal}}}{${function.is-optimized} [opt]}{${frame.is-artificial} [artificial]}
"

因此我们可以在调试中打印 bp 、 sp ,例如

frame #10: 0x208895c4: pc:0x208895c4,fp:0x01f7d458,sp:0x01f7d414   UIKit`-[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 376

更多信息请见https://lldb.llvm.org/use/formatting.html

解决方案 10:

您可以使用以下内容:

uint32_t msp_value = __get_MSP(); // Read Main Stack pointer

如果你想获取PSP值,方法如下:

uint32_t psp_value = __get_PSP(); // Read Process Stack pointer

如果要使用汇编语言,也可以使用MSP和PSP流程:

MRS R0, MSP // Read Main Stack pointer to R0
 
MRS R0, PSP // Read Process Stack pointer to R0
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   681  
  在项目管理领域,集成产品开发(IPD)流程以其高效、协同的特点,被众多企业视为提升产品竞争力的关键。IPD流程强调跨部门、跨职能的紧密合作,以确保产品从概念到市场各个环节的无缝衔接。然而,实现这一目标并非易事,它需要企业深刻理解并掌握IPD流程中的跨部门协作艺术。本文将深入探讨IPD流程中跨部门协作的三个关键点,旨在为...
IPD项目管理咨询   9  
  掌握IPD流程图:提升团队协作的关键路径在当今快速变化的商业环境中,团队协作的效率与效果直接关系到项目的成功与否。集成产品开发(Integrated Product Development,简称IPD)作为一种先进的研发管理理念,通过跨部门、跨领域的协同工作,能够显著提升产品开发的速度与质量。而IPD流程图,则是这一理...
IPD流程阶段   9  
  IPD流程概述:理解其核心价值与实施背景集成产品开发(Integrated Product Development,简称IPD)是一种先进的产品开发管理理念,它强调跨部门协作、市场导向和快速响应变化的能力。IPD流程不仅关注产品本身的技术创新,更注重将市场、研发、生产、销售等各个环节紧密集成,以实现产品从概念到市场的高...
华为IPD是什么   7  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程以其跨部门协作、高效决策和快速响应市场变化的特点,被众多企业视为提升竞争力的关键。然而,实践IPD流程并非易事,项目管理中的种种错误往往阻碍了其效果的充分发挥。本文旨在深入探讨如何在实施IPD流程时避免这些常见错误,...
IPD框架   7  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用