coredump推栈
linux coredump里面的code 解析
linux coredump里面的code 解析摘要:1.Linux coredump 背景介绍2.Linux coredump 文件结构解析3.Linux coredump 中的code 段解析4.Linux coredump 中code 段的实际应用案例5.总结正文:Linux coredump 是Linux 系统中的一种重要调试工具,可以帮助开发者分析程序崩溃的原因。
在coredump 文件中,包含了程序崩溃时的一些关键信息,如进程状态、内存信息等。
其中,code 段是coredump 中非常重要的一个部分,它包含了程序的执行代码。
Linux coredump 文件结构解析Linux coredump 文件主要包括以下几个部分:- magic:魔数,用于标识coredump 文件类型,固定为0x8130。
- version:版本信息,表示coredump 文件格式版本,当前为2。
- header:coredump 文件头,包含文件类型、进程ID、时间戳等信息。
- body:coredump 文件主体,包含进程的内存映像,包括code 段、data 段、bss 段等。
Linux coredump 中的code 段解析code 段是coredump 中存储程序执行代码的部分,通常以ELF (Executable and Linkable Format)格式存储。
ELF 是一种可执行文件格式,支持多种处理器架构。
code 段包含了程序的指令和数据,以及符号表等信息。
在ELF 文件中,code 段分为两种:text 段和data 段。
text 段包含了程序的执行代码,而data 段包含了程序的数据。
这两个段通过动态链接器(dynamic linker)链接在一起,形成一个完整的可执行文件。
Linux coredump 中code 段的实际应用案例假设我们有一个程序崩溃了,产生了coredump 文件。
应用程序运行时产生coredump故障处理
应用程序运行时产生coredump故障处理环境:操作系统:AIX Common 数据库:无关应用程序:32-bit症状:客户应用结息程序在运行过程中产生coredump。
程序故障与处理数据量有关,当把结息网点分成两批,可以顺利完成。
解决方法:应用程序的问题本来不属于我们维保的范畴,因为客户关系比较好,开发商太极公司也是我们的友军,抱着试试看的态度来解决。
用svmon跟踪程序的执行,发现其在运行期间,work process private部分的内存增长速度非常快,并且很明显地,接近65536页的时候即发生core dump。
这表明程序故障与内存的过度使用有关,达到256MB阀值时溢出。
work process private与用户程序的堆、栈有关,其中堆常为malloc系统调用分配的内存空间。
这里与ulimit设置无关(已经设置为unlimited),与AIX 32位程序的内存分配行为有关。
32位程序最多可以使用16个内存段,其中segment 2~C用户可用作堆栈和共享内存,默认仅使用segment 2存放程序堆栈数据,最大值为256MB,所以默认情况下用户程序最多只能分配256MB的堆内存。
而这个默认行为,可以通过在执行程序前,设置LDR_CNTRL环境变量来调节堆栈部分和共享内存的比例,例如:LDR_CNTRL=MAXDATA=0x30000000,设置了堆栈内存空间最多可使用3个内存段,共768MB 内存。
下面是一个测试的例子:# include <stdio.h>main (){int i;unsigned char *p;i=0;while ( i < 20 ){printf ( "i=%d\n", i );/* 32M */p=(unsigned char *)malloc(33554432);memset(p,'\0',33554432);i=i+1;sleep(1);}sleep(120);}直接运行该程序,在i=7之后产生coredump,采用下面的方式执行命令:# LDR_CNTRL=MAXDATA=0x3000000 ./testmalloc程序能够正常执行结束运行,同时运行的svmon显示程序已经使用到了256MB以上的堆空间。
linux内核堆栈解析方法
在 Linux 系统中,内核堆栈(kernel stack)用于执行内核代码。
当发生操作系统内核崩溃、内核出现异常或需要调试时,理解和分析内核堆栈十分重要。
以下是分析 Linux 内核堆栈的常用方法:使用dmesg:当内核发生故障时,错误信息和堆栈追踪通常会输出到内核日志。
你可以使用 dmesg 命令查看内核日志中的堆栈追踪。
dmesg | grep -i stack操作系统崩溃时的系统日志:有时通过分析内核崩溃时的系统日志(如/var/log/syslog 或/var/log/messages、/var/log/kern.log)也可以找到有关堆栈信息。
使用 dump_stack() 函数:在内核代码中,你可以使用 dump_stack() 函数打印当前线程的堆栈信息。
这在调试内核代码时非常有用。
系统核心转储(Core Dump):内核崩溃时,操作系统有时会生成系统核心转储文件。
你可以使用 GNU Debugger(GDB)来分析内核转储文件。
首先,安装 Linux 的调试符号表(debugging symbols),然后使用 gdb 命令加载符号表和内核转储文件,最后使用 bt(backtrace)命令查看堆栈追踪。
gdb path/to/vmlinux path/to/core_dump(gdb) bt请注意,要使内核生成核心转储文件,需要正确配置内核。
具体配置方法取决于你所使用的 Linux 发行版。
内核调试器(如 KGDB 和 KDB):如果你正在研究内核问题,可以使用内核调试器 KGDB 或 KDB。
KGDB 是基于 GDB 的内核调试器,可以在源代码级别进行调试。
KDB 则是一个基于文本的内核调试器。
使用这些工具,你可以从内核级别设置断点、单步执行代码、检查内存内容和调用堆栈等。
通过以上方法可以帮助你分析 Linux 内核堆栈。
如何选择最佳方法取决于你的具体需求和问题。
在进行内核调试之前,请确保熟悉 Linux 操作系统和内核开发的基本知识。
pthread之线程堆栈分配不足coredump分析
先来讲说线程内存相关的东西,主要有下面几条:1.进程中的所有的线程共享相同的地址空间。
2.任何声明为static/extern的变量或者堆变量可以被进程内所有的线程读写。
3.一个线程真正拥有的唯一私有储存是处理器寄存器。
4.线程栈可以通过暴露栈地址的方式与其它线程进行共享。
有大数据量处理的应用中,有时我们有必要在栈空间分配一个大的内存块或者要分配很多小的内存块,但是线程的栈空间的最大值在线程创建的时候就已经定下来了,如果栈的大小超过个了个值,系统将访问未授权的内存块,毫无疑问,再来的肯定是一个段错误。
可是没办法,你还是不得不分配这些内存,于是你开会为分配一个整数值而动用malloc这种超级耗时的操作。
当然,在你的需求可以评估的情况下,你的需求还是可以通过修改线程的栈空间的大小来改变的。
下面的我们用pthread_attr_getstacksize和pthread_attr_setstacksize的方法来查看和设置线程的栈空间。
注意:下面的测试代码在我自己的机子上(ubuntu6.06,ubuntu6.10,redhat 9, gentoo)通过了测试,但是很奇怪的是在我同事的机子上,无论是改变环境,还是想其它方法都不能正常的运行。
在网上查了一下,很多人也存在同样的问题,至今不知道为何。
linux线程的实现方式决定了对进程的限制同样加在了线程身上:)所以,有问题,请参见<pthread之线程栈空间(2)(进行栈)直接看代码吧,只有一个C文件(thread_attr.c)#include <limits.h>#include <pthread.h>#include "errors.h"//线程体,在栈中分配一个大小为15M的空间,并进行读写void *thread_routine (void *arg){printf ("The thread is here\n");//栈大小为16M,如果直接分配16M的栈空间,会出现段错误,因为栈中还有其它的//变量要放署char p[1024*1024*15];int i=1024*1024*15;//确定内存分配的确成功了while(i--){p[i] = 3;}printf( "Get 15M Memory\n" );//分配更多的内存(如果分配1024*1020*512的话就会出现段错误) char p2[ 1024 * 1020 + 256 ];memset( p2, 0, sizeof( char ) * ( 1024 * 1020 + 256 ) );printf( "Get More Memory\n" );return NULL;}int main (int argc, char *argv[]){pthread_t thread_id;pthread_attr_t thread_attr;size_t stack_size;int status;status = pthread_attr_init (&thread_attr);if (status != 0)err_abort (status, "Create attr");status = pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED);if (status != 0)err_abort (status, "Set detach");//通常出现的问题之一,下面的宏没有定义#ifdef _POSIX_THREAD_ATTR_STACKSIZE//得到当前的线程栈大小status = pthread_attr_getstacksize (&thread_attr, &stack_size); if (status != 0)err_abort (status, "Get stack size");printf ("Default stack size is %u; minimum is %u\n",stack_size, PTHREAD_STACK_MIN);//设置当前的线程的大小status = pthread_attr_setstacksize (&thread_attr, PTHREAD_STACK_MIN*1024);if (status != 0)err_abort (status, "Set stack size");//得到当前的线程栈的大小status = pthread_attr_getstacksize (&thread_attr, &stack_size);if (status != 0)err_abort (status, "Get stack size");printf ("Default stack size is %u; minimum is %u\n",stack_size, PTHREAD_STACK_MIN);#endifint i = 5;//分配5个具有上面的属性的线程体while(i--){status = pthread_create (&thread_id, &thread_attr, thread_routine, NULL); if (status != 0)err_abort (status, "Create thread");}getchar();printf ("Main exiting\n");pthread_exit (NULL);return 0;}看看执行过程:dongq@DongQ_Lap ~/workspace/test/pthread_attr $ makecc -pthread -g -DDEBUG -lrt -o thread_attr thread_attr.cdongq@DongQ_Lap ~/workspace/test/pthread_attr $ ./thread_attrDefault stack size is 8388608; minimum is 16384 //默认的栈大小为8MDefault stack size is 16777216; minimum is 16384 //设置后的结果为16MThe thread is hereThe thread is hereThe thread is hereThe thread is hereThe thread is hereGet 15M MemoryGet More MemoryGet 15M MemoryGet More MemoryGet 15M MemoryGet 15M MemoryGet More MemoryGet More MemoryGet 15M MemoryGet More MemoryMain exitings用下面的命令来看linux下面的对系统的一些限制:dongq@DongQ_Lap ~/workspace/test/pthread_attr $ ulimit -acore file size (blocks, -c) 0data seg size (kbytes, -d) unlimitedscheduling priority (-e) 0file size (blocks, -f) unlimitedpending signals (-i) 16365max locked memory (kbytes, -l) 32max memory size (kbytes, -m) unlimitedopen files (-n) 1024pipe size (512 bytes, -p) 8POSIX message queues (bytes, -q) 819200real-time priority (-r) 0stack size (kbytes, -s) 8196cpu time (seconds, -t) unlimitedmax user processes (-u) 16365virtual memory (kbytes, -v) unlimitedfile locks (-x) unlimited通过上面的命令,我们可以清楚的看到一个进程在正常的情况下,最大的栈空间为8M。
C++ Core dump问题定位方法
return 0; }
该程序分别启动两个线程,线程 1 和线程 2 由于都在等待对方设置信号量为 FLASE,后退出线程,互相等待导致死锁。
这时抓取 Core dump 的方法跟上面提到的一样,不同的是,这时只需要抓 取内存的快照,不需要一开始就运行 adplus,只要在发现有线程死锁现象时运 行 adplus,并把-crash 参数改为-hang,即可。
2、 何谓 Core dump 我们在开发(或使用)一个程序时,最怕的就是程序莫明其妙地当掉。虽然
系统没事,但我们下次仍可能遇到相同的问题。于是这时操作系统就会把程序当 掉时的内存内容 dump 出来(现在通常是写在一个叫 core 的文件里面,不同 操作系统下的名称可能不同),让我们或是调试器做为参考,进行问题定位。这 个动作就叫作 Core dump。
3、 为何会发生 Core dump 前面说过,在程序当掉时出错。C/C++语言中,最常发生错误的地方就是
指针有问题。您可以利用 core 文件和调试器把错误找出来。
4、 Core dump 适用范围 Core dump 适用于定位 C++程序内存错误、线程死锁等复杂问题,特别是
当程序在用户机子上出现内存问题时,通过日志一般也很难定位出来(由于程序 当了,写日志的线程也跟着程序结束了,错误信息很可能没有写到日志里),这 种情况只有通过获取当时的 Core dump 文件来定位,没有第二种方法了。
命令解释如下: 参数 crash:用于捕获 Coredump; pn:用于指定所需监视的进程名称; o(小写字母):用于指示所捕获 Core dump 文件输出目录; 由于 Core dump 写入的是出现问题时内存的信息,因此输出的 dump 文 件可能会比较大从几 M 到几 G 不定,根据当时出现问题的具体情况,因此在指 定 Core dump 输出目录时,最好指定在空间比较大的磁盘下。当执行 adplus 后,在“o”参数指定的路径下,可以看到多了一个目录,一般目录名称为:” Crash_Mode__Date_01-18-2010__Time_18-49-4343”,即 Crash 开头,后接 Core dump 产生的日期、时间。里面会有“ADPlus_report.txt”、“PID-3324__ DGISPOWERMODEL.EXE__Date_01-18-2010__Time_19-11-2424.log ” 、 “Process_List.txt”三个文件,记录了程序运行时的进程信息等,可以用记事本 打开查看。 当发生 Core dump 后,这个目录下就会多三个以“.dmp”为后缀名的文 件文件(一般是三个,有时也可能只有一个)。三个文件一般两个里面有包含 “1st”、一个包含“2nd”的字样,这个是跟 windows 系统异常捕获机制分为 两阶段处理有关,具体可以 Google 下,不具体解释。这三个文件就是 Core
pthread之线程堆栈分配不足coredump分析
先来讲说线程内存相关的东西,主要有下面几条:1.进程中的所有的线程共享相同的地址空间。
2.任何声明为static/extern的变量或者堆变量可以被进程内所有的线程读写。
3.一个线程真正拥有的唯一私有储存是处理器寄存器。
4.线程栈可以通过暴露栈地址的方式与其它线程进行共享。
有大数据量处理的应用中,有时我们有必要在栈空间分配一个大的内存块或者要分配很多小的内存块,但是线程的栈空间的最大值在线程创建的时候就已经定下来了,如果栈的大小超过个了个值,系统将访问未授权的内存块,毫无疑问,再来的肯定是一个段错误。
可是没办法,你还是不得不分配这些内存,于是你开会为分配一个整数值而动用malloc这种超级耗时的操作。
当然,在你的需求可以评估的情况下,你的需求还是可以通过修改线程的栈空间的大小来改变的。
下面的我们用pthread_attr_getstacksize和pthread_attr_setstacksize的方法来查看和设置线程的栈空间。
注意:下面的测试代码在我自己的机子上(ubuntu6.06,ubuntu6.10,redhat 9, gentoo)通过了测试,但是很奇怪的是在我同事的机子上,无论是改变环境,还是想其它方法都不能正常的运行。
在网上查了一下,很多人也存在同样的问题,至今不知道为何。
linux线程的实现方式决定了对进程的限制同样加在了线程身上:)所以,有问题,请参见<pthread之线程栈空间(2)(进行栈)直接看代码吧,只有一个C文件(thread_attr.c)#include <limits.h>#include <pthread.h>#include "errors.h"//线程体,在栈中分配一个大小为15M的空间,并进行读写void *thread_routine (void *arg){printf ("The thread is here\n");//栈大小为16M,如果直接分配16M的栈空间,会出现段错误,因为栈中还有其它的//变量要放署char p[1024*1024*15];int i=1024*1024*15;//确定内存分配的确成功了while(i--){p[i] = 3;}printf( "Get 15M Memory!!!\n" );//分配更多的内存(如果分配1024*1020*512的话就会出现段错误) char p2[ 1024 * 1020 + 256 ];memset( p2, 0, sizeof( char ) * ( 1024 * 1020 + 256 ) );printf( "Get More Memory!!!\n" );return NULL;}int main (int argc, char *argv[]){pthread_t thread_id;pthread_attr_t thread_attr;size_t stack_size;int status;status = pthread_attr_init (&thread_attr);if (status != 0)err_abort (status, "Create attr");status = pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED);if (status != 0)err_abort (status, "Set detach");//通常出现的问题之一,下面的宏没有定义#ifdef _POSIX_THREAD_ATTR_STACKSIZE//得到当前的线程栈大小status = pthread_attr_getstacksize (&thread_attr, &stack_size); if (status != 0)err_abort (status, "Get stack size");printf ("Default stack size is %u; minimum is %u\n",stack_size, PTHREAD_STACK_MIN);//设置当前的线程的大小status = pthread_attr_setstacksize (&thread_attr, PTHREAD_STACK_MIN*1024);if (status != 0)err_abort (status, "Set stack size");//得到当前的线程栈的大小status = pthread_attr_getstacksize (&thread_attr, &stack_size);if (status != 0)err_abort (status, "Get stack size");printf ("Default stack size is %u; minimum is %u\n",stack_size, PTHREAD_STACK_MIN);#endifint i = 5;//分配5个具有上面的属性的线程体while(i--){status = pthread_create (&thread_id, &thread_attr, thread_routine, NULL); if (status != 0)err_abort (status, "Create thread");}getchar();printf ("Main exiting\n");pthread_exit (NULL);return 0;}看看执行过程:dongq@DongQ_Lap ~/workspace/test/pthread_attr $ makecc -pthread -g -DDEBUG -lrt -o thread_attr thread_attr.cdongq@DongQ_Lap ~/workspace/test/pthread_attr $ ./thread_attrDefault stack size is 8388608; minimum is 16384 //默认的栈大小为8MDefault stack size is 16777216; minimum is 16384 //设置后的结果为16MThe thread is hereThe thread is hereThe thread is hereThe thread is hereThe thread is hereGet 15M Memory!!!Get More Memory!!!Get 15M Memory!!!Get More Memory!!!Get 15M Memory!!!Get 15M Memory!!!Get More Memory!!!Get More Memory!!!Get 15M Memory!!!Get More Memory!!!Main exitings用下面的命令来看linux下面的对系统的一些限制:dongq@DongQ_Lap ~/workspace/test/pthread_attr $ ulimit -acore file size (blocks, -c) 0data seg size (kbytes, -d) unlimitedscheduling priority (-e) 0file size (blocks, -f) unlimitedpending signals (-i) 16365max locked memory (kbytes, -l) 32max memory size (kbytes, -m) unlimitedopen files (-n) 1024pipe size (512 bytes, -p) 8POSIX message queues (bytes, -q) 819200real-time priority (-r) 0stack size (kbytes, -s) 8196cpu time (seconds, -t) unlimitedmax user processes (-u) 16365virtual memory (kbytes, -v) unlimitedfile locks (-x) unlimited通过上面的命令,我们可以清楚的看到一个进程在正常的情况下,最大的栈空间为8M。
linux core dump 默认路径
linux core dump 默认路径"Linux Core Dump默认路径"在Linux操作系统中,当一个进程遇到严重错误导致其异常终止时,会生成一个core dump文件。
Core dump文件包含了进程在崩溃时的内存信息,可以被用于调试和分析问题。
在本文中,我将介绍Linux Core Dump的默认路径,并一步一步回答这个问题。
1. 了解core dump当一个进程出现崩溃时,操作系统会默认生成一个core dump文件。
Core dump文件具有与崩溃进程在崩溃时的内存镜像,其包含了进程在崩溃时的状态信息,如寄存器的值、进程的环境变量以及堆栈信息。
这个文件对于系统管理员和开发人员来说非常有用,因为它提供了分析和解决崩溃问题的线索。
2. Linux Core Dump的默认路径在Linux系统中,core dump文件的默认路径是由操作系统的设置决定的。
通常情况下,core dump文件会被存储在进程当前工作目录下,以文件名"core"作为前缀,后面跟随一个数字后缀以区分不同的core dump文件。
例如,"core.1234",其中"1234"是崩溃进程的PID(进程ID)。
3. 修改core dump文件的默认路径如果你希望将core dump文件存储在特定的路径下,你可以通过修改Linux系统的设置来完成。
以下是一些修改core dump文件默认路径的方法。
a. 修改ulimit设置:对于每个用户,可以使用"ulimit"命令来设置core dump文件的路径。
"ulimit"命令用于限制用户的资源使用,包括core dump文件的大小和位置。
要修改core dump文件的默认路径,你可以使用以下命令:ulimit -c unlimited这将允许core dump文件的大小不受限制。
protobuf = 赋值触发的coredump
你提到的“protobuf = 赋值触发的coredump”似乎是在描述一个与Google的Protocol Buffers(通常简称为protobuf)相关的问题,其中某个赋值操作导致了程序崩溃并生成了core dump文件。
核心转储(core dump)是当程序崩溃时由操作系统生成的文件,它包含了程序崩溃时的内存镜像和一些关于崩溃的上下文信息。
这通常对于调试非常有用,因为它可以帮助开发者定位到导致崩溃的代码位置。
如果在使用protobuf时遇到了这样的问题,以下是一些建议的调试步骤:1.检查core dump文件:使用gdb或其他调试工具打开core dump文件,并尝试获取崩溃时的堆栈跟踪信息。
这可以帮助你定位到导致崩溃的具体代码位置。
2.检查赋值操作:仔细审查导致崩溃的赋值操作。
确保你没有尝试访问无效的内存地址,或者没有超出数组或字符串的边界。
3.protobuf版本:确保你使用的protobuf库与你的代码和proto文件兼容。
有时,不同版本的protobuf之间可能存在不兼容性。
4.内存管理:确保正确地管理了protobuf对象的生命周期。
例如,不要在一个protobuf对象被释放后再次使用它,也不要尝试修改一个const protobuf对象。
5.编译选项:确保你的程序在编译时启用了适当的调试信息和优化级别。
这样,当程序崩溃时,你可以更容易地获取有用的调试信息。
6.其他库和依赖:确保你的程序链接了所有必要的库,并且这些库是兼容的。
7.简化问题:尝试简化你的代码,创建一个最小的可重现问题的示例。
这可以帮助你更容易地定位问题,并可能使问题变得更明显。
8.查阅文档和社区:查阅protobuf的官方文档和社区论坛,看看是否有其他人遇到了类似的问题,并查找可能的解决方案。
qnx coredump解析
qnx coredump解析解析QNX coredump需要使用QNX的开发工具集合,其中包括NOA(Network of Applications),用于分析和解析QNX coredump文件。
以下是一个基本的QNX coredump解析过程的示例:1. 在QNX开发系统上安装NOA工具集合。
这需要登录QNX官方网站并下载适用于您的操作系统和体系结构的NOA工具包。
2. 使用`gdb`命令行工具打开QNX coredump文件。
例如,`gdb core dumpfile`。
3. 在`gdb`命令行下,可以使用多种命令来分析和解析QNX coredump文件。
一些常用的命令包括:- `bt`:显示堆栈回溯信息,指示在崩溃时调用堆栈上的函数。
- `frame`:显示当前堆栈帧。
- `info registers`:显示寄存器的值。
- `print`或`p`:打印变量的值。
- `quit`:退出`gdb`。
4. 使用这些命令可以分析QNX coredump文件并找到导致崩溃的原因。
根据具体的情况,可能需要进一步分析代码或根据堆栈回溯信息调试问题。
请注意,QNX和gdb命令的用法可能因版本和配置而有所不同,此处提到的命令仅供参考。
您可以查阅相关文档以获取更详细的信息。
另外,如果您使用的是QNX Momentics IDE开发环境,它提供了一个内置的分析工具,可以更方便地分析和解析QNX coredump文件。
通过Momentics IDE的图形用户界面,您可以打开coredump文件并浏览各个线程的调用堆栈、变量值等信息。
linux coredump机制
linux coredump机制1. 引言1.1 概述Linux Coredump机制是一种操作系统级别的功能,可以在程序崩溃或异常终止时生成一个dump文件,记录了程序崩溃时的内存状态和堆栈信息。
Coredump文件包含了导致崩溃的关键信息,能够帮助开发人员进行故障诊断和问题排查。
本文将介绍Linux Coredump机制的原理、配置和参数设置方法,以及如何分析和利用Coredump文件进行调试与故障处理。
1.2 文章结构本文总共分为五个部分,每个部分都有明确的主题内容。
第一部分是引言部分,首先概述了Linux Coredump机制的基本概念,并介绍了文章的结构和目录。
接下来四个部分依次介绍了Linux Coredump机制的详细内容,包括Coredump生成过程、配置和参数设置、Coredump文件的分析与利用方法等。
最后一部分是总结与展望,对Linux Coredmu机制进行一个总结,并展望其可能的改进方向和发展前景。
1.3 目的本文旨在深入探讨Linux Coredump机制,在读者理解其原理基础上详细介绍其具体实现方法和使用技巧。
通过本文的学习,读者可以了解到如何配置和启用Coredump功能,以及如何利用Coredump文件进行故障诊断和问题排查。
同时,本文也希望能够引发读者对Linux Coredump机制的思考与讨论,鼓励其在实际开发过程中积极应用这一功能,并探索其可能的改进方向和未来发展前景。
2. Linux Coredump机制:2.1 Coredump简介:Coredump是指在软件运行过程中发生了错误或异常情况时,操作系统会将程序当前的内存状态以文件的形式保存下来。
Coredump文件记录了程序在崩溃前的内存数据、寄存器值、堆栈信息等重要调试信息。
它对于故障诊断和问题排查非常有用。
2.2 Coredump生成过程:当一个程序出现了严重错误导致崩溃时,操作系统会为该进程生成一个Coredump文件。
coredump文件考出解析
coredump文件考出解析Core Dump文件是指在计算机程序运行时,出现异常情况导致程序崩溃时所生成的一种文件。
这个文件记录了程序在崩溃时的内存状态信息,包含了程序运行时的堆栈信息、寄存器状态以及其他相关的调试信息等。
通过分析Core Dump文件,可以帮助开发人员定位和解决程序崩溃的问题。
Core Dump文件的解析对于软件开发人员来说是一项非常重要的技能,可以帮助他们快速定位和修复程序中的bug。
下面就让我们来了解一下Core Dump文件的解析过程吧。
要解析Core Dump文件,我们需要借助一些调试工具。
常用的调试工具有GDB(GNU Debugger)、LLDB(LLVM Debugger)等。
这些工具可以加载Core Dump文件,并提供一系列命令和功能来分析和调试程序。
解析Core Dump文件的第一步是加载文件。
使用调试工具加载Core Dump文件后,我们可以查看文件中的各种信息。
比如,我们可以查看程序崩溃时的堆栈信息,了解程序在崩溃前的执行路径。
通过分析堆栈信息,我们可以确定程序崩溃的位置,找出导致程序崩溃的原因。
除了堆栈信息,Core Dump文件还包含了程序崩溃时的内存状态信息。
我们可以通过查看内存状态,了解程序在崩溃前的变量值、函数调用等信息。
这对于定位程序崩溃的原因非常有帮助。
在解析Core Dump文件时,我们还可以使用调试工具提供的其他功能,比如查看变量的值、设置断点、单步执行等。
这些功能可以帮助我们进一步分析和调试程序。
在进行Core Dump文件解析时,我们需要注意以下几点。
首先,要保证使用的调试工具版本与生成Core Dump文件的程序版本一致,以免出现兼容性问题。
其次,要注意文件的大小,如果Core Dump 文件过大,可能需要分析工具支持加载大文件。
此外,要注意保护好Core Dump文件的安全,避免泄露敏感信息。
除了使用调试工具解析Core Dump文件,还有一些第三方工具和库可以帮助我们更方便地分析Core Dump文件。
coredump配置、产生、分析以及分析示例
coredump配置、产⽣、分析以及分析⽰例关键词:coredump、core_pattern、coredump_filter等等。
应⽤程序在运⾏过程中由于各种异常或者bug导致退出,在满⾜⼀定条件下产⽣⼀个core⽂件。
通常core⽂件包含了程序运⾏时内存、寄存器状态、堆栈指针、内存管理信息以及函数调⽤堆栈信息。
core就是程序当前⼯作转改存储⽣成的⼀个⽂件,通过⼯具分析这个⽂件,可以定位到程序异常退出的时候对应的堆栈调⽤等信息,找出问题点并解决。
1. 配置coredump如果需要使⽤需要通过ulimit进⾏设置,可以通过ulimit -c查看当前系统是否⽀持coredump。
如果为0,则表⽰coredump被关闭。
通过ulimit -c unlimited可以打开coredump。
coredump⽂件默认存储位置与可执⾏⽂件在同⼀⽬录下,⽂件名为core。
可以通过/proc/sys/kernel/core_pattern进⾏设置。
%p 出Core进程的PID%u 出Core进程的UID%s 造成Core的signal号%t 出Core的时间,从1970-01-0100:00:00开始的秒数%e 出Core进程对应的可执⾏⽂件名通过echo "core-%e-%p-%s-%t" > /proc/sys/kernel/core_pattern。
在每个进程下都有coredump_filter节点/proc/<pid>/coredump_filter。
通过配置coredump_filter可以选择需在coredump的时候,将哪些内容dump到core⽂件中。
- (bit 0) anonymous private memory- (bit 1) anonymous shared memory- (bit 2) file-backed private memory- (bit 3) file-backed shared memory- (bit 4) ELF header pages in file-backed private memory areas (it is effective only if the bit 2is cleared)- (bit 5) hugetlb private memory- (bit 6) hugetlb shared memory- (bit 7) DAX private memory- (bit 8) DAX shared memorycoredump_filter的默认值是0x33,也即发⽣coredump时会将所有anonymous内存、ELF头页⾯、hugetlb private memory内容保存。
linux coredump机制
linux coredump机制(原创版)目录1.Linux 内核概要2.核心转储机制概述3.核心转储的触发条件4.核心转储文件的生成与存储5.核心转储文件的调试与分析6.配置核心转储选项7.结论正文1.Linux 内核概要Linux 内核是 Linux 操作系统的核心,它负责管理系统的资源和协调系统中各种组件的运行。
内核由一系列模块组成,这些模块分别负责不同的功能,如进程管理、内存管理、文件系统等。
内核的运行状态可以通过/proc 文件系统来查看和调整。
2.核心转储机制概述核心转储(core dump)机制是指当一个进程在运行过程中发生异常,如内存错误、段错误等,导致进程无法继续运行时,操作系统将该进程的当前状态(包括进程的代码、数据、堆栈等信息)保存到一个磁盘文件中,以便开发人员进行调试和分析。
核心转储文件通常以.core 为扩展名,如core.12345。
3.核心转储的触发条件核心转储的触发条件主要有以下几种:(1)程序本身请求核心转储,如通过设置 ulimit -c 命令来开启核心转储功能。
(2)接收到外部信号,如 SIGSEGV、SIGTERM 等。
(3)操作系统检测到内部错误,如内存错误、段错误等。
4.核心转储文件的生成与存储当一个进程发生异常时,操作系统会将该进程的状态保存到内核缓冲区。
然后,操作系统会将缓冲区中的数据写入到一个磁盘文件中,生成核心转储文件。
核心转储文件的存储路径通常可以在/proc/sys/kernel/corepattern 文件中配置。
5.核心转储文件的调试与分析开发人员可以使用调试工具,如 gdb、objdump 等,对核心转储文件进行调试和分析。
通过分析核心转储文件,开发人员可以找到程序崩溃的原因,进而修改程序代码,提高程序的稳定性。
6.配置核心转储选项可以通过修改/proc/sys/kernel/corepattern文件来配置核心转储的选项,如文件名、大小限制等。
linux coredump文件产生原理
在Linux系统中,coredump文件是当进程异常终止时由操作系统生成的。
当进程由于收到信号、运行时错误、硬件异常等原因异常终止时,操作系统会将进程的当前内存快照保存到coredump文件中,以便后续分析和调试。
coredump文件的生成原理如下:
当进程异常终止时,操作系统会通过信号机制通知进程,并生成coredump文件。
操作系统会选择一个合适的文件路径和文件名来保存coredump文件。
默认情况下,coredump文件会被保存在当前目录下,文件名为“core”。
操作系统会将进程的内存快照保存到coredump文件中。
这个快照包括了进程的代码段、数据段、堆、栈等内存区域的内容。
coredump文件中还包括了进程的寄存器状态、信号屏蔽状态等信息,这些信息对于后续的调试和分析非常重要。
生成coredump文件的过程是由内核来完成的,因此需要在内核配置中启用coredump功能。
在Linux系统中,可以通过修
改/etc/security/limits.conf文件来设置允许生成coredump文件的用户和大小限制。
在程序运行时,也可以通过设置ulimit命令来控制coredump文件的生成。
总之,coredump文件是Linux系统中非常重要的调试工具,通过它可以帮助开发人员快速定位和解决问题。
关于Segmentationfault(coredumped)
关于Segmentationfault(coredumped)有的程序可以通过编译,但在运⾏时会出现Segment fault(段错误)。
这通常都是指针错误引起的。
但这不像编译错误⼀样会提⽰到⽂件⼀⾏,⽽是没有任何信息。
⼀种办法是⽤gdb的step, ⼀步⼀步寻找。
但要step⼀个上万⾏的代码让⼈难以想象。
我们还有更好的办法,这就是core file。
如果想让系统在信号中断造成的错误时产⽣core⽂件, 我们需要在shell中按如下设置:#设置core⼤⼩为⽆限 ulimit -c unlimited#设置⽂件⼤⼩为⽆限 ulimit unlimited发⽣core dump之后,⽤gdb进⾏查看core⽂件的内容, 以定位⽂件中引发core dump的⾏:gdb [exec file] [core file]如: gdb ./test test.core 在进⼊gdb后,⽤bt命令查看backtrace以检查发⽣程序运⾏到哪⾥,来定位core dump的⽂件->⾏。
另外需要注意的是,如果你的机器上跑很多的应⽤,你⽣成的core⼜不知道是哪个应⽤产⽣的,你可以通过下列命令进⾏查看:file core⼏个问题:1. 什么是Core:在使⽤半导体作为内存的材料前,⼈类是利⽤线圈当作内存的材料(发明者为王安),线圈就叫作 core ,⽤线圈做的内存就叫作 core memory。
如今,半导体⼯业澎勃发展,已经没有⼈⽤core memory 了,不过,在许多情况下,⼈们还是把记忆体叫作 core 。
2. 什么是Core Dump:我们在开发(或使⽤)⼀个程序时,最怕的就是程序莫明其妙地当掉。
虽然系统没事,但我们下次仍可能遇到相同的问题。
于是这时操作系统就会把程序当掉时的内存内容 dump 出来(现在通常是写在⼀个叫 core 的 file ⾥⾯),让我们或是 debugger 做为参考。
这个动作就叫作 core dump。
gdb调试coredump原理 -回复
gdb调试coredump原理-回复GDB调试coredump原理引言:在开发过程中,我们经常会遇到程序崩溃的情况。
为了定位程序崩溃的原因,我们需要进行调试。
而在调试过程中,有一种特殊的情况,叫做coredump。
当一个程序发生严重错误或崩溃时,操作系统会生成一个core文件,记录程序崩溃时的内存状态。
通过调试这个core文件,我们可以更加方便地找到程序的问题所在。
本文将以gdb调试coredump为主题,详细介绍其原理和使用方法。
一、什么是coredump?Coredump指的是当一个程序因为错误而异常终止时,操作系统将程序的内存状态保存到一个特殊的文件中,即core文件。
这个core文件包含了程序崩溃时的内存状态、寄存器的状态以及函数、变量的信息。
对于GDB 来说,这个core文件就是一个可调试的文件,我们可以使用GDB来调试这个文件,进一步定位程序错误的原因。
二、生成coredump文件的配置生成coredump文件的配置主要涉及到操作系统的配置和程序的编译配置。
1. 操作系统配置大多数Unix-like系统默认是开启coredump功能的,但有时会被禁用。
我们可以通过下面的命令来查看系统是否开启了coredump功能:ulimit -c如果输出为0,则表示未开启,大于0则表示开启。
我们可以通过下面的命令来开启coredump功能,并设置生成的core文件大小:ulimit -c unlimitedulimit -c <size>其中,<size>指的是core文件的大小,单位为字节。
2. 编译配置在编译程序时,我们需要添加-g选项来启用调试信息的产生。
例如,我们可以使用gcc编译C程序时,添加如下的命令行选项:gcc -g -o program program.c通过以上配置,就可以在程序崩溃时生成core文件。
三、使用GDB调试coredump文件1. 命令行方式通过命令行方式使用GDB调试coredump文件非常简单,只需指定coredump文件和可执行文件即可。
死机出现coredump
在开发和使用Linux 程序时,引擎有时会莫名其妙的core 掉,在网上查了一下,整理了一个简单的调试core 文件的方法。
1、什么是core dump?Core,即core memory,而dump 就是堆放的意思。
core dump 又叫核心转储,当程序运行过程中发生异常,程序异常退出时,由操作系统把程序当前的内存状况存储在一个core 文件中,叫core dump。
2、如何打开core dump支持?有的操作系统并没有默认打开core dump 支持,需要用ulimit -c unlimited 语句进行设置,core 文件生成的位置一般在程序运行的当前目录下,文件名为core. 进程号( 当然不同的系统也许有所不同,可以查看相手册对路径和文件名进行设置).3、Core dump的使用方法首先应该在用gcc 进行编译时选择-g 选项,以便起动debug 支持,生成可执行文件是ex,./ex 运行可执行文件,如果程序当掉,则会生成一个core 文件,假设为core.1568,则gdb excore.1568 进入gdb,然后再用where 命令进行查看即可。
先看看我用的是个什么机器:# uname -aLinux localhost.localdomain 2.6.23.1-42.fc8 #1 SMP Tue Oct 30 13:55:12 EDT 2007 i686 i686 i386 GNU/Linux再看看默认的一些参数:(注意core file size是个0,程序出错时不会产生core 文件了)$ ulimit -a如果未设置 ulimit –c unlimited corefile size就是0,即使core dump,也无法生产core文件。
开发板上的一般如下图:写个简单的程序,看看core 文件是不是会被产生。
(代码略)$ gcc -Wall -g foo.c$ ./a.outSegmentation fault$ ls -l core.*ls: core.*: No such file or directory没有找到core 文件,我们改改ulimit 的设置,让它产生。
linux coredump机制
linux coredump机制Linux的coredump机制是指在程序发生崩溃或错误时,将程序的堆栈、寄存器、内存状态等信息保存在一个称为core文件的特殊文件中,以供开发者进行调试和分析。
下面是关于Linux coredump机制的相关参考内容。
一、Core Dump的概念和作用Core Dump是指在程序崩溃或错误发生时,将程序的内存镜像保存到一个特殊文件中。
这个文件被称为core文件。
Core Dump记录了程序崩溃时的内存状态,包括程序计数器、寄存器、堆栈等信息。
Core Dump的作用主要有以下几个方面:1. 调试:开发人员可以使用Core Dump来分析程序崩溃的原因,找出问题所在,进行调试和修复。
2. 内存泄漏检测:通过分析Core Dump,可以检测程序中的内存泄漏问题,优化程序的内存使用。
3. 性能分析:通过分析程序的Core Dump,可以了解程序执行时的内存占用情况、CPU使用情况等,优化程序的性能。
二、Core Dump的生成和设置Core Dump的生成由操作系统控制,可以通过以下几种方式进行设置:1. ulimit命令:可以使用ulimit命令设置core文件的大小限制,默认为0表示不生成core文件。
可以使用ulimit -c命令查看和设置core文件大小限制。
2. /proc文件系统:可以通过设置/proc/sys/kernel/core_pattern文件来控制core文件的生成位置和文件名格式,例如:echo "/tmp/core-%e-%p-%t" > /proc/sys/kernel/core_pattern上述命令将core文件生成在/tmp目录下,文件名的格式为"core-程序名-进程ID-时间戳"3. shell命令:使用shell脚本或命令来捕获程序的core dump,并进行处理。
例如,在可执行程序上添加以下命令来捕获core dump:ulimit -c unlimited然后使用gdb或其他调试工具进行core文件的分析和调试。
gdb调试coredump使用
gdb调试coredump使⽤什么是coredump?Coredump叫做核⼼转储,它是进程运⾏时在突然崩溃的那⼀刻的⼀个内存快照。
操作系统在程序发⽣异常⽽异常在进程内部⼜没有被捕获的情况下,会把进程此刻内存、寄存器状态、运⾏堆栈等信息转储保存在⼀个⽂件⾥。
该⽂件也是⼆进制⽂件,可以使⽤gdb、elfdump、objdump或者windows下的windebug、solaris下的mdb进⾏打开分析⾥⾯的具体内容。
ulimit -c 可以设置core⽂件的⼤⼩,如果这个值为0.则不会产⽣core⽂件,这个值太⼩,则core⽂件也不会产⽣,因为core⽂件⼀般都⽐较⼤。
使⽤ulimit -c unlimited来设置⽆限⼤,则任意情况下都会产⽣core⽂件。
ulimit -a可以查看当前core⽂件限制。
1、设置core⽂件的名称和⽂件路径默认⽣成路径:输⼊可执⾏⽂件运⾏命令的同⼀路径下默认⽣成名字:默认命名为core。
新的core⽂件会覆盖旧的core⽂件a.设置pid作为⽂件扩展名1:添加pid作为扩展名,⽣成的core⽂件名称为core.pid0:不添加pid作为扩展名,⽣成的core⽂件名称为core修改 /proc/sys/kernel/core_uses_pid ⽂件内容为: 1修改⽂件命令: echo "1" > /proc/sys/kernel/core_uses_pid或者sysctl -w kernel.core_uses_pid=1 kernel.core_uses_pid = 12、控制core⽂件保存位置和⽂件名格式修改⽂件命令: echo "/corefile/core-%e-%p-%t" > /proc/sys/kernel/core_pattern或者:sysctl -w kernel.core_pattern=/corefile/core-%e-%p-%t kernel.core_pattern = /corefile/core-%e-%p-%t可以将core⽂件统⼀⽣成到/corefile⽬录下,产⽣的⽂件名为core-命令名-pid-时间戳以下是参数列表:%p - insert pid into filename 添加pid(进程id)%u - insert current uid into filename 添加当前uid(⽤户id)%g - insert current gid into filename 添加当前gid(⽤户组id)%s - insert signal that caused the coredump into the filename 添加导致产⽣core的信号%t - insert UNIX time that the coredump occurred into filename 添加core⽂件⽣成时的unix时间%h - insert hostname where the coredump happened into filename 添加主机名%e - insert coredumping executable name into filename 添加导致产⽣core的命令名gdb 调试coredump的简单⽰例#include "stdio.h"#include "stdlib.h"void dumpCrash(){char *ptr = "test";free(ptr);}int main(){dumpCrash();return0;}如上代码,pStr指针指向的是字符串常量,字符串常量是保存在常量区的,free释放常量区的内存肯定会导致coredump。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
在调试程序的过程中经常回碰到segment fault的问题,我们通常的办法是用gdb调试生成的coredump文件。
下面以一个简单的例子来分析下用gdb调试coredump文件中的无法看到调用栈的问题。
用例源码:此程序编译后运行会segment fault,下面用gdb分析下生成的coredump文件。
首先我们要看的是调用栈的情况:(gdb) bt#0 0x43676e69 in ?? ()#1 0x6f4e6e62 in ?? ()#2 0x6f745374 in ?? ()#3 0x57735570 in ?? ()#4 0x08040065 in ?? ()#5 0x00000003 in ?? ()#6 0xbf9dfa0d in ?? ()#7 0xbf9de748 in ?? ()#8 0x08048440 in wrapper3 (level=Cannot access memory at address 0x68746f56) at test.c:24Backtrace stopped: previous frame inner to this frame (corrupt stack?)如果碰到调用栈如上所示显示为??的问题,分析coredump文件就比较棘手了。
这种情况下我们尝试下看能不能手动的推栈。
首先看下寄存器信息(gdb) i registerseax 0x6f4e6e62 1867411042ecx 0x0 0edx 0x7ea0d0 8298704ebx 0x7e8ff4 8294388esp 0xbf9de720 0xbf9de720ebp 0x68746f4e 0x68746f4eesi 0x69eca0 6941856edi 0x0 0eip 0x43676e69 0x43676e69eflags 0x10202 [ IF RF ]cs 0x73 115ss 0x7b 123ds 0x7b 123es 0xc040007b -1069547397fs 0x0 0gs 0x33 51函数在调用过程中,会按照一定的约定规则,压入变量、参数和返回地址进入栈空间,我们根据esp和ebp指针值来分析栈空间的布局情况。
上面的寄存器栈信息中,ebp的值比esp的值要大,这个明显是不符合栈的空间布局规律的。
一个函数的栈空间中,ebp位于高地址,esp位于低地址,ebp>=esp(gdb) x/10x 0x68746f4e0x68746f4e: Cannot access memory at address 0x68746f4e(gdb) x/40x 0xbf9de7200xbf9de720: 0x6f4e6e62 0x6f745374 0x57735570 0x080400650xbf9de730: 0x00000003 0xbf9dfa0d0xbf9de748 0x080484400xbf9de740: 0x00000002 0xbf9dfa0d 0xbf9de768 0x080484820xbf9de750: 0x00000001 0xbf9dfa0d 0xbf9de778 0xbf9de7800xbf9de760: 0x00692600 0xbf9de780 0xbf9de7d8 0x006bce9c0xbf9de770: 0x0069eca0 0x080484b0 0xbf9de7d8 0x006bce9c0xbf9de780: 0x00000002 0xbf9de804 0xbf9de810 0x0069f8100xbf9de790: 0x00000000 0x00000001 0x00000001 0x000000000xbf9de7a0: 0x007e8ff4 0x0069eca0 0x00000000 0xbf9de7d80xbf9de7b0: 0x84f983cd 0x3b0faa2c 0x00000000 0x00000000Ebp的值是不合法的,我们可以看到ebp所指向的栈空间的内容。
Esp的内容为0xbf9de720,ebp的值肯定大于此值。
根据压栈情况,ebp+4位置为返回地址。
我们再来看下bt看到的调用栈信息,第8层栈能够看到函数wrapper3信息,我们到第8层栈看下什么情况(gdb) f 8#8 0x08048440 in wrapper3 (level=Cannot access memory at address 0x68746f56) at test.c:2424 return wrapper2( ++level, str );看到wrapper3函数调用wrapper2的时刻,参数level不合法反汇编wrapper3函数看看(gdb) disassemble wrapper3Dump of assembler code for function wrapper3:0x08048424 <wrapper3+0>: push %ebp0x08048425 <wrapper3+1>: mov %esp,%ebp0x08048427 <wrapper3+3>: sub $0x8,%esp0x0804842a <wrapper3+6>: addl $0x1,0x8(%ebp)0x0804842e <wrapper3+10>: mov 0xc(%ebp),%eax0x08048431 <wrapper3+13>: mov %eax,0x4(%esp)0x08048435 <wrapper3+17>: mov 0x8(%ebp),%eax0x08048438 <wrapper3+20>: mov %eax,(%esp)0x0804843b <wrapper3+23>: call 0x8048406 <wrapper2>0x08048440 <wrapper3+28>: leave0x08048441 <wrapper3+29>: retEnd of assembler dump.根据汇编代码,我们看下栈空间的情况,调用wrapper2函数之前的栈空间esp(说明:这里栈空间图中,高地址在上,低地址在下,下面的图也是如此)看下此层栈(第8层栈)下相关寄存器的信息(gdb) i r esp ebpesp 0xbf9de740 0xbf9de740ebp 0x68746f4e 0x68746f4e可以看到此时esp的值为0xbf9de740,其指向的内容如下:0xbf9de740: 0x00000002 0xbf9dfa0d 0xbf9de768 0x08048482(gdb) x/s 0xbf9dfa0d0xbf9dfa0d: "WeAreHumanBeingsNothingCanNotStopUsWe"也就是level=2,str指向0xbf9dfa0d,ebp指针指向0xbf9de768,返回地址为0x08048482 (gdb) info symbol 0x08048482main + 64 in section .text of /mnt/hgfs/centos/test根据反汇编代码看到wrapper3函数会调用wrapper2,接着反汇编wrapper2函数看看(gdb) disassemble wrapper2Dump of assembler code for function wrapper2:0x08048406 <wrapper2+0>: push %ebp0x08048407 <wrapper2+1>: mov %esp,%ebp0x08048409 <wrapper2+3>: sub $0x8,%esp0x0804840c <wrapper2+6>: addl $0x1,0x8(%ebp)0x08048410 <wrapper2+10>: mov 0xc(%ebp),%eax0x08048413 <wrapper2+13>: mov %eax,0x4(%esp)0x08048417 <wrapper2+17>: mov 0x8(%ebp),%eax0x0804841a <wrapper2+20>: mov %eax,(%esp)0x0804841d <wrapper2+23>: call 0x80483e8 <wrapper1>0x08048422 <wrapper2+28>: leave0x08048423 <wrapper2+29>: retEnd of assembler dump.调用wrapper2函数之后的栈空间如下所示esp也就是level=2,str指向0xbf9dfa0d,ebp指针指向0xbf9de748,返回地址为0x08048440 (gdb) info symbol 0x08048440wrapper3 + 28 in section .text of /mnt/hgfs/centos/test这正好说明此层栈为wrapper2函数的栈空间。
根据反汇编代码看到wrapper2函数会调用wrapper1,接着反汇编wrapper1函数(gdb) disassemble wrapper1Dump of assembler code for function wrapper1:0x080483e8 <wrapper1+0>: push %ebp0x080483e9 <wrapper1+1>: mov %esp,%ebp0x080483eb <wrapper1+3>: sub $0x8,%esp0x080483ee <wrapper1+6>: addl $0x1,0x8(%ebp)0x080483f2 <wrapper1+10>: mov 0xc(%ebp),%eax0x080483f5 <wrapper1+13>: mov %eax,0x4(%esp)0x080483f9 <wrapper1+17>: mov 0x8(%ebp),%eax0x080483fc <wrapper1+20>: mov %eax,(%esp)0x080483ff <wrapper1+23>: call 0x80483b4 <overflow>0x08048404 <wrapper1+28>: leave0x08048405 <wrapper1+29>: retEnd of assembler dump.调用wrapper1函数之后的栈空间如下所示esp同理前面的推断,这里esp值应该为0xbf9de720,其指向的内容如下:0xbf9de720: 0x6f4e6e62 0x6f745374 0x57735570 0x08040065比较栈空间对应的值level=0x6f4e6e62为错误值,str指向的0x6f745374,也是错误值;ebp 指针指向0x57735570(应该为0xbf9de738)错误;(gdb) disassemble 0x08040065No function contains specified address.可见返回地址也是错误值0x08040065这些信息也正好和coredump文件中寄存器信息的esp指向0xbf9de720,eax=0x6f4e6e62情况符合。