打印出堆栈指针的值

2024-11-14 08:29:00
admin
原创
20
摘要:问题描述:如何在 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
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用