打印出堆栈指针的值

2024-11-14 08:29:00
admin
原创
233
摘要:问题描述:如何在 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
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1142  
  IPD(Integrated Product Development,集成产品开发)流程是一种广泛应用于高科技和制造业的产品开发方法论。它通过跨职能团队的紧密协作,将产品开发周期缩短,同时提高产品质量和市场成功率。在IPD流程中,CDCP(Concept Decision Checkpoint,概念决策检查点)是一个关...
IPD培训课程   96  
  研发IPD(集成产品开发)流程作为一种系统化的产品开发方法,已经在许多行业中得到广泛应用。它不仅能够提升产品开发的效率和质量,还能够通过优化流程和资源分配,显著提高客户满意度。客户满意度是企业长期成功的关键因素之一,而IPD流程通过其独特的结构和机制,能够确保产品从概念到市场交付的每个环节都围绕客户需求展开。本文将深入...
IPD流程   87  
  IPD(Integrated Product Development,集成产品开发)流程是一种以跨职能团队协作为核心的产品开发方法,旨在通过优化资源分配、提高沟通效率以及减少返工,从而缩短项目周期并提升产品质量。随着企业对产品上市速度的要求越来越高,IPD流程的应用价值愈发凸显。通过整合产品开发过程中的各个环节,IPD...
IPD项目管理咨询   95  
  跨部门沟通是企业运营中不可或缺的一环,尤其在复杂的产品开发过程中,不同部门之间的协作效率直接影响项目的成败。集成产品开发(IPD)作为一种系统化的项目管理方法,旨在通过优化流程和增强团队协作来提升产品开发的效率和质量。然而,跨部门沟通的复杂性往往成为IPD实施中的一大挑战。部门之间的目标差异、信息不对称以及沟通渠道不畅...
IPD是什么意思   92  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用