【问题标题】:Core dump when I want to get the init stack infomation当我想获取初始化堆栈信息时的核心转储
【发布时间】:2021-04-18 17:10:03
【问题描述】:

我写了一个小测试来尝试打印程序的初始化堆栈,这里是代码

#include <stdio.h>
#include <elf.h>

int main(int argc, char* argv[])
{
    int *p = (int*)argv;
    int i;
    Elf32_auxv_t* aux;
    printf("Argument count: %d\n", *(p - 1));
    
    for (int i = 0; i < *(p - 1); ++i)
    {
        printf("Argument %d : %s\n", i, *(p + i));
    }
    
    p+=i;    
    p++;
    printf("Enviroment\n");
    
    while (*p)
    {
        printf("%s\n", *p);
        p++;
    }
    
    p++;
    
    printf("Auxiliary Vector\n");
    aux = (Elf32_auxv_t*)p;
    while (aux->a_type != AT_NULL)
    {
        printf("Type: %02d Value: %x\n", aux->a_type, aux->a_un.a_val);
        aux++;
    }
    
    return 0;

}

我想看到的是打印环境指针和 AT_PHDR、AT_PHENT、AT_PHNUM、AT_ENTRY 和 AT_NULL。但结果显示这里是一个核心转储

Argument count: 0
Enviroment
Segmentation fault (core dumped)

程序有什么问题?感谢您的帮助。

【问题讨论】:

  • 请注意,mainthird 参数讨论不多(指向环境的指针):int main(int argc,char **argv,char **envp) 如果您在某些拱门上(例如 @ 987654325@)、argcargvenvp不在堆栈上。它们在寄存器中:(分别为%edi%rsi%rdx)。如果您想查看/转储初始 堆栈,您需要 __builtin_frame_address(0) 并执行(例如):char **vp = __builtin_frame_address(0); for (int idx = 0; idx &lt; 32; ++idx, ++vp) printf("%d: %p %p\n",idx,vp,*vp);
  • @Craig Estey 感谢您的回复。那么这个程序可能只能在32位系统上运行?

标签: c linux stack coredump


【解决方案1】:

这是我的顶级评论的开头。

感谢您的回复。所以这个程序可能只能在32位系统上运行。

可以 [排序] 使用(例如):

void *vp = &argc;

这将 不是 是 64 位的真实帧。编译器会将argc 存储到main 的堆栈帧中的一个虚拟区域中并指向它。它与 32 位类似,但又不完全相同。

但是......你的指针算法有点脆弱(例如):

printf("Argument count: %d\n", *(p - 1));

不会很好用。

这是我编写的一些代码,用于[基本上]您正在做的事情,但以一种干净(更)的方式:

#include <stdio.h>

int glob_argc;
char **glob_argv;
char **glob_envp;
void *glob_frame;

void
showframe(void)
{
    char **vp = glob_frame;

    for (int idx = 0;  idx < 32;  ++idx, ++vp)
        printf("%d: %p %p\n",idx,vp,*vp);
}

int
main(int argc,char **argv,char **envp)
{

    glob_argc = argc;
    glob_argv = argv;
    glob_envp = envp;

    glob_frame = __builtin_frame_address(0);
    printf("glob_frame=%p\n",glob_frame);

    printf("glob_argc=%d\n",glob_argc);
    printf("glob_argv=%p\n",glob_argv);
    printf("glob_envp=%p\n",glob_envp);
    showframe();

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-20
    • 1970-01-01
    相关资源
    最近更新 更多