如何找出发生SEGV内存找出错误的版本号程序

I'm debugging a crash reported as:
Exception Type:
Exception Codes: SEGV_ACCERR
The crash is happening on the line that does numberOfFails++.
The app uses ASIHTTP. I personally much prefer using NSURLConnection. I'd never automatically repeat a request for NSURLConnection if it failed because I've never seen it fail when it shouldn't. I'd rather just give the UI a refresh button or show a UIAlertView with a button to try again or something like that.
Anyway, to cooperate with other team members, I'm looking to fix this issue without replacing ASIHTTP with NSURLConnection for now.
The request is being started with something like:
- (void)getResources:(CLLocation *)location withQuery:(NSString *)query {
NSURL *url = [NSURL URLWithString:[NSString stringWithString:@"/"]];
self.resourcesAPIRequest = [ASIFormDataRequest requestWithURL:url];
[resourcesAPIRequest setPostValue:[Model instance].oauth_token forKey:@"oauth_token"];
[resourcesAPIRequest setPostValue:[[NSNumber numberWithDouble:location.coordinate.latitude] stringValue] forKey:@"latitude"];
[resourcesAPIRequest setPostValue:[[NSNumber numberWithDouble:location.coordinate.longitude] stringValue] forKey:@"longitude"];
[resourcesAPIRequest setPostValue:query forKey:@"query"];
[resourcesAPIRequest setDelegate:self];
[resourcesAPIRequest setDidFinishSelector:@selector(resourcesAPIReturned:)];
resourcesAPIRequest.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:NSStringFromSelector(@selector(getResources:withQuery:)), @"repeatSelector", location, @"argument1", query, @"argument2", nil];
[resourcesAPIRequest startAsynchronous];
One thing I noticed is : &ASIHTTPRequestDelegate& is not in the header file, but this callback method is still being called OK:
#define maximumNumberOfFails 50
- (void)requestFailed:(ASIFormDataRequest *)request {
static int numberOfFails = 0;
if (numberOfFails & maximumNumberOfFails) {
[NSThread sleepForTimeInterval:sleepTimeInSeconds];
if ([request.userInfo objectForKey:@"argument2"]) {
[self performSelector:NSSelectorFromString([request.userInfo objectForKey:@"repeatSelector"]) withObject:[request.userInfo objectForKey:@"argument1"] withObject:[request.userInfo objectForKey:@"argument2"]];
} else if ([request.userInfo objectForKey:@"argument1"]) {
[self performSelector:NSSelectorFromString([request.userInfo objectForKey:@"repeatSelector"]) withObject:[request.userInfo objectForKey:@"argument1"]];
[self performSelector:NSSelectorFromString([request.userInfo objectForKey:@"repeatSelector"])];
numberOfFails++;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Problem" message:@"There was a problem connecting to the servers.
Please make sure you have an Internet connection." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
numberOfFails = 0;
Also, I think that static int numberOfFails should be static NSUInteger numberOfFails. And, I noticed that the request is started with startAsynchronous. Is static int numberOfFails atomic? That may be why we're getting the error SEGV_ACCERR (Invalid permissions for mapped object).
解决方案 The problem likely has nothing to do with your static variable.
Does requestFailed: execute on the main thread, or in a background thread?
If it's on a background thread, you'll need to use performSelectorOnMainThread:withObject:.
If it's on the main thread, you may need to take a pass through the runloop before executing a new HTTP request.
To do that, use performSelector:withObject:afterDelay:, and pass '0.0' as the delay.
You'll notice that both those methods allow only a single method parameter.
Typically, you pass your parameters in a NSDictionary rather than try to parse out the number of parameters beforehand, like you're doing.
本文地址: &
我正在调试崩溃报告为:
异常类型:SIGSEGV 异常代码:SEGV_ACCERR
崩溃发生在 numberOfFails ++
应用程序使用 ASIHTTP 。我个人更喜欢使用 NSURLConnection 。我永远不会自动重复请求 NSURLConnection 如果失败,因为我从来没有看到它失败,当它不应该。我宁愿只给UI一个刷新按钮,或者用一个按钮显示一个 UIAlertView ,再试一次或类似的东西。
无论如何,与其他团队成员合作,我正在寻找解决这个问题,而不用 ASIHTTP 替换 NSURLConnection </$ c $
- (void)getResources:(CLLocation *)location withQuery:(NSString *)query { NSURL * url = [NSURL URLWithString:[NSString stringWithString:@“/” ];
self.resourcesAPIRequest = [ASIFormDataRequest requestWithURL:url];
[resourcesAPIRequest setPostValue:[Model instance] .oauth_token forKey:@“oauth_token”];
[resourcesAPIRequest setPostValue:[[NSNumber numberWithDouble:location.coordinate.latitude] stringValue] forKey:@“latitude”];
[resourcesAPIRequest setPostValue:[[NSNumber numberWithDouble:location.coordinate.longitude] stringValue] forKey:@“longitude”];
[resourcesAPIRequest setPostValue:query forKey:@“query”];
[resourcesAPIRequest setDelegate:self];
[resourcesAPIRequest setDidFinishSelector:@selector(resourcesAPIReturned :)];
resourcesAPIRequest.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:NSStringFromSelector(@selector(getResources:withQuery :)),@“repeatSelector”,location,@“argument1”,query,@“argument2”,nil]
[resourcesAPIRequest startAsynchronous]; }
我注意到的一件事是:& ASIHTTPRequestDelegate& 不在头文件中,但此回调方法仍在调用确定:
#define maximumNumberOfFails 50
- (void)requestFailed:(ASIFormDataRequest *)request { static int numberOfFails = 0;
if(numberOfFails& maximumNumberOfFails){ [NSThread sleepForTimeInterval:sleepTimeInSeconds];
if([request.userInfo objectForKey:@“argument2”]){ [self performSelector:NSSelectorFromString([request.userInfo objectForKey:@“repeatSelector”])withObject:[request.userInfo objectForKey:@ “argument1”] withObject:[request.userInfo objectForKey:@“argument2”]]; } else if([request.userInfo objectForKey:@“argument1”]){ [self performSelector:NSSelectorFromString([request.userInfo objectForKey:@“repeatSelector”])withObject:[request.userInfo objectForKey :@“argument1”]]; } else { [self performSelector:NSSelectorFromString([request.userInfo objectForKey:@“repeatSelector”])]; }
numberOfFails ++; } else { UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@“Problem”message:@“连接到服务器时出现问题,请确保您已连接到互联网。 delegate:nil cancelButtonTitle:@“Ok”otherButtonTitles:nil];
[alert show];
[alert release];
numberOfFails = 0; } }
static int numberOfFails 应该是 static NSUInteger numberOfFails 。并且,我注意到请求是以 startAsynchronous 开始的。是 static int numberOfFails
atomic?这可能是为什么我们得到错误 SEGV_ACCERR (映射对象的权限无效)。
想法? / p>
解决方案 此问题可能与您的静态变量无关。
requestFailed:在主线程或后台线程中执行吗?
如果是在后台线程,你需要使用 performSelectorOnMainThread:withObject:。
如果它在主线程上,您可能需要在执行新的HTTP请求之前通过runloop。为此,使用 performSelector:withObject:afterDelay:,并传递'0.0'作为延迟。
将注意到这两种方法只允许一个方法参数。通常,你在 NSDictionary 中传递你的参数,而不是像你一样尝试解析参数的数量。
本文地址: &
扫一扫关注官方微信如何检测在C / C ++程序可能/潜在的堆栈溢出问题?-c++,c,内存memory,stack,溢出overflow-CodeGo.net
如何检测在C / C ++程序可能/潜在的堆栈溢出问题?
有没有一种标准的方法,看看有多少堆栈空间的应用程序有什么最高的水印是在运行过程中?
此外,在实际的溢出可怕的情况下会发生什么?
它会崩溃,触发异常或信号?是否有一个标准或者是在所有系统上的不同
我要找专门用于Windows,Linux和Macintosh。
本文地址 :CodeGo.net/11508/
-------------------------------------------------------------------------------------------------------------------------
1. 在Windows堆栈溢出异常将会产生。
下面的窗口代码这样:
#include &stdio.h&
#include &windows.h&
void StackOverFlow()
// we are interested control registers
context.ContextFlags = CONTEXT_CONTROL;
// get the details
GetThreadContext(GetCurrentThread(), &context);
// print the stack pointer
printf("Esp: %X\n", context.Esp);
// this will eventually overflow the stack
StackOverFlow();
DWORD ExceptionFilter(EXCEPTION_POINTERS *pointers, DWORD dwException)
return EXCEPTION_EXECUTE_HANDLER;
void main()
// we are interested control registers
context.ContextFlags = CONTEXT_CONTROL;
// get the details
GetThreadContext(GetCurrentThread(), &context);
// print the stack pointer
printf("Esp: %X\n", context.Esp);
// cause a stack overflow
StackOverFlow();
__except(ExceptionFilter(GetExceptionInformation(), GetExceptionCode()))
printf("\n****** ExceptionFilter fired ******\n");
当此exe文件运行下面的输出生成:
Esp: 12FC4C
Esp: 12F96C
Esp: 12F68C
Esp: 33D8C
Esp: 33AAC
Esp: 337CC
****** ExceptionFilter fired ******
在Linux上你会得到一个错误,如果你的代码试图写栈。
堆的大小是继承过程之间的一个属性。如果你能在类似的命令读取或修改它ulimit -s(在sh,ksh,zsh)或limit stacksize(tcsh,zsh)。
从一个节目时,堆栈的大小可以是
#include &sys/resource.h&
#include &stdio.h&
getrlimit(RLIMIT_STACK, &l);
printf("stack_size = %d\n", l.rlim_cur);
我不知道一个标准的方式来获取可用堆栈的大小。
该协议栈开始argc随后的内容argv和,然后你的变量的副本。然而 CodeGo.net,内核可以随机堆叠的开始的位置,并且可以有上述虚设值argc,这将是错误的,你有l.rlim_cur下面可用字节&argc。
检索堆栈的确切位置的一种方法是查看文件/proc/1234/maps(其中1234是你的程序的进程ID).a旦你知道这些界限你多少你的一叠通过查看最新的本地变量的地址。
gcc的地方的返回地址和“不安全”函数调用,就像普通的变量之间的一个额外的块(在这个例子中,函数是无效的测试(){char数据类型的[10],B [20]}
call stack:
-----------
return address
char b[10]
char a[20]
如果函数写入36个字节的指针&#39;A&#39;,溢出将&#39;腐败&#39;的返回地址(可能的安全漏洞)。但它也将改变&#39;假&#39;的值,也就是指针,返回地址之间,所以程序将警告崩溃(你可以禁用这个用选项-fno-堆栈保护器)
在Windows下,栈(用于特定线程)增长点播,直到该线程的创建之前指定的堆栈大小已达到。
点播日益增长的使用保护页,在那有一个唯一的堆栈的使用开始,随后是保护页,其中,当命中,将触发异常-这个异常是特殊的,并且是由系统为您处理-处理增加了可用的堆栈空间(也检查如果一个已达到限制!)和读操作重试。
一旦达到限制,没有更多的生长而导致堆栈溢出异常。
当前堆栈基和限制都存储在线程块,在一个叫做结构_NT_TIB(块)。
如果你有一个调试方便,这就是你所看到的:
0:000& dt ntdll!_teb @$teb nttib.
+0x000 NtTib :
+0x000 ExceptionList : 0x _EXCEPTION_REGISTRATION_RECORD
+0x004 StackBase : 0x
+0x008 StackLimit : 0x
+0x00c SubSystemTib : (null)
+0x010 FiberData : 0x00001e00
+0x010 Version : 0x1e00
+0x014 ArbitraryUserPointer : (null)
+0x018 Self : 0x7ffdf000 _NT_TIB
该StackLimit属性将得到更新点播。
如果您检查块的属性,你会看到类似:
0:000& !address 0x
MEM_PRIVATE
PAGE_READWRITE
MEM_COMMIT
Usage RegionUsageStack
Pid.Tid abc.560
并检查旁边有一个页面显示的后卫属性:
0:000& !address 0x0
MEM_PRIVATE
PAGE_READWRITE | PAGE_GUARD
MEM_COMMIT
Usage RegionUsageStack
Pid.Tid abc.560
希望它可以帮助。
在Linux上,gnulibsigsegv库包括函数stackoverflow_install_handler,它可以检测(和案件协助您从恢复)堆栈溢出。
堆栈溢出可能是最讨厌的类型的异常处理-你的异常处理程序来处理堆栈极少量(通常只有一个页面被保留用于此目的)。
为了处理这种类型的异常的困难一个有趣的看到这些博客文章:1和2的克里斯从网络的视角,尤其是宿主CLR的问题。
这是在Visual Studio中改变堆栈大小可能EDITBIN。可以在MSDN上找到。
编译器支持stackavail()函数,该函数返回剩余的堆栈的可用空间量。你这个函数调用函数在程序中需要大量的堆栈空间,以确定它是否是安全的,给他们打电话之前
我建议你备份信号堆栈,如果你是在Linux上。
在这种情况下,所有的信号将在交替叠层进行处理。
万一发生堆栈溢出,系统会生成一个SEGV信号,这可以通过备份堆栈处理。
如果你这样做......那么你可能无法处理信号,你的程序可能会崩溃,没有任何处理/埃罗汇报。
本文标题 :如何检测在C / C ++程序可能/潜在的堆栈溢出问题?
本文地址 :CodeGo.net/11508/
Copyright (C) 2017 CodeGo.net>> 如何找出发生SEGV内存错误的程序Linux环境下段错误的产生原因及调试方法,Linux,环境,下段,错误,产生,原因,调试,方法,_LINUX_【联盟电脑】
您现在的位置: >
Linux环境下段错误的产生原因及调试方法
1. 段错误是什么一句话来说,段错误是指访问的内存超出了系统给这个程序所设定的内存空间,例如访问了不存在的内存地址、访问了系统保护的内存地址、访问了只读的内存地址等等情况。这里贴一个对于“段错误”的准确定义(参考):A segmentation fault (often shortened to segfault) is a particular error condition that can occur during the operation of computer software. In short, a segmentation fault occurs when a program attempts to access a memory location that it is not allowed to access, or attempts to access a memory location in a way that is not allowed (e.g., attempts to write to a read-only location, or to overwrite part of the operating system). Systems based on processors like the Motorola 68000 tend to refer to these events as Address or Bus errors.Segmentation is one approach to memory management and protection in the operating system. It has been superseded by paging for most purposes, but much of the terminology of segmentation is still used, &segmentation fault& being an example. Some operating systems still have segmentation at some logical level although paging is used as the main memory management policy.On Unix-like operating systems, a process that accesses invalid memory receives the SIGSEGV signal. On Microsoft Windows, a process that accesses invalid memory receives the STATUS_ACCESS_VIOLATION exception.2. 段错误产生的原因2.1 访问不存在的内存地址#include&stdio.h&#include&stdlib.h&void main(){& & & & int *ptr = NULL;& & & & *ptr = 0;}2.2 访问系统保护的内存地址#include&stdio.h&#include&stdlib.h&void main(){& & & & int *ptr = (int *)0;& & & & *ptr = 100;}2.3 访问只读的内存地址#include&stdio.h&#include&stdlib.h&#include&string.h&void main(){& & & & char *ptr = &test&;& & & & strcpy(ptr, &TEST&);}2.4 栈溢出#include&stdio.h&#include&stdlib.h&void main(){& & & & main();}等等其他原因。3. 段错误信息的获取程序发生段错误时,提示信息很少,下面有几种查看段错误的发生信息的途径。3.1 dmesgdmesg可以在应用程序crash掉时,显示内核中保存的相关信息。如下所示,通过dmesg命令可以查看发生段错误的程序名称、引起段错误发生的内存地址、指令指针地址、堆栈指针地址、错误代码、错误原因等。以程序2.3为例::~/segfault$ dmesg[ ] segfault3[2700]: segfault at 80484e0 ip 00d2906a sp bfbbec3c error 7 in libc-2.10.1.so[cbe000]3.2 -g使用gcc编译程序的源码时,加上-g参数,这样可以使得生成的二进制文件中加入可以用于gdb调试的有用信息。以程序2.3为例::~/segfault$ gcc -g -o segfault3 segfault3.c3.3 nm使用nm命令列出二进制文件中的符号表,包括符号地址、符号类型、符号名等,这样可以帮助定位在哪里发生了段错误。以程序2.3为例::~/segfault$ nm segfault d _DYNAMIC08049ff4 d _GLOBAL_OFFSET_TABLE_080484dc R _IO_stdin_used& & & & &w _Jv_RegisterClasses08049f10 d __CTOR_END__08049f0c d __CTOR_LIST__08049f18 D __DTOR_END__08049f14 d __DTOR_LIST__080484ec r __FRAME_END__08049f1c d __JCR_END__08049f1c d __JCR_LIST__ A __bss_start0804a00c D __data_start t __do_global_ctors_aux t __do_global_dtors_aux D __dso_handle& & & & &w __gmon_start__0804848a T __i686.get_pc_thunk.bx08049f0c d __init_array_end08049f0c d __init_array_start T __libc_csu_fini T __libc_csu_init& & & & &U __libc_start_main@@GLIBC_2. A _edata0804a01c A _end080484bc T _fini R _fp_hw080482bc T _init T _start b completed.c W data_start b dtor_idx.c0 t frame_dummy T main& & & & &U memcpy@@GLIBC_2.03.4 ldd使用ldd命令查看二进制程序的共享链接库依赖,包括库的名称、起始地址,这样可以确定段错误到底是发生在了自己的程序中还是依赖的共享库中。以程序2.3为例::~/segfault$ ldd ./segfault3& & linux-gate.so.1 =& &(0x00e08000)& & libc.so.6 =& /lib/tls/i686/cmov/libc.so.6 (0x)& & /lib/ld-linux.so.2 (0x. 段错误的调试方法4.1 使用printf输出信息这个是看&#20284;最简单但往往很多情况下十分有效的调试方式,也许可以说是程序员用的最多的调试方式。简单来说,就是在程序的重要代码附近加上像printf这类输出信息,这样可以跟踪并打印出段错误在代码中可能出现的位置。为了方便使用这种方法,可以使用条件编译指令#ifdef DEBUG和#endif把printf函数包起来。这样在程序编译时,如果加上-DDEBUG参数就能查看调试信息;否则不加该参数就不会显示调试信息。4.2 使用gcc和gdb4.2.1 调试步骤&1、为了能够使用gdb调试程序,在编译阶段加上-g参数,以程序2.3为例::~/segfault$ gcc -g -o segfault3 segfault3.c2、使用gdb命令调试程序::~/segfault$ gdb ./segfault3&GNU gdb (GDB) 7.0-ubuntuCopyright (C) 2009 Free Software Foundation, Inc.License GPLv3&#43;: GNU GPL version 3 or later &http://gnu.org/licenses/gpl.html&This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law. &Type &show copying&and &show warranty& for details.This GDB was configured as &i486-linux-gnu&.For bug reporting instructions, please see:&http://www.gnu.org/software/gdb/bugs/&...Reading symbols from /home/panfeng/segfault/segfault3...done.(gdb)&3、进入gdb后,运行程序:(gdb) runStarting program: /home/panfeng/segfault/segfault3&Program received signal SIGSEGV, Segmentation fault.0x001a306a in memcpy () from /lib/tls/i686/cmov/libc.so.6(gdb)&从输出看出,程序2.3收到SIGSEGV信号,触发段错误,并提示地址0x001a306a、调用memcpy报的错,位于/lib/tls/i686/cmov/libc.so.6库中。4、完成调试后,输入quit命令退出gdb:(gdb) quitA debugging session is active.& & Inferior 1 [process 3207] will be killed.Quit anyway? (y or n) y4.2.2 适用场景1、仅当能确定程序一定会发生段错误的情况下使用。2、当程序的源码可以获得的情况下,使用-g参数编译程序。3、一般用于测试阶段,生产环境下gdb会有副作用:使程序运行减慢,运行不够稳定,等等。4、即使在测试阶段,如果程序过于复杂,gdb也不能处理。4.3 使用core文件和gdb在4.2节中提到段错误会触发SIGSEGV信号,通过man 7 signal,可以看到SIGSEGV默认的handler会打印段错误出错信息,并产生core文件,由此我们可以借助于程序异常退出时生成的core文件中的调试信息,使用gdb工具来调试程序中的段错误。4.3.1 调试步骤1、在一些Linux版本下,默认是不产生core文件的,首先可以查看一下系统core文件的大小限制::~/segfault$ ulimit -c02、可以看到默认设置情况下,本机Linux环境下发生段错误时不会自动生成core文件,下面设置下core文件的大小限制(单位为KB)::~/segfault$ ulimit -c :~/segfault$ ulimit -c10243、运行程序2.3,发生段错误生成core文件::~/segfault$ ./segfault3段错误 (core dumped)4、加载core文件,使用gdb工具进行调试::~/segfault$ gdb ./segfault3 ./core&GNU gdb (GDB) 7.0-ubuntuCopyright (C) 2009 Free Software Foundation, Inc.License GPLv3&#43;: GNU GPL version 3 or later &http://gnu.org/licenses/gpl.html&This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law. &Type &show copying&and &show warranty& for details.This GDB was configured as &i486-linux-gnu&.For bug reporting instructions, please see:&http://www.gnu.org/software/gdb/bugs/&...Reading symbols from /home/panfeng/segfault/segfault3...done.warning: Can't read pathname for load map: 输入/输出错误.Reading symbols from /lib/tls/i686/cmov/libc.so.6...(no debugging symbols found)...done.Loaded symbols for /lib/tls/i686/cmov/libc.so.6Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.Loaded symbols for /lib/ld-linux.so.2Core was generated by `./segfault3'.Program terminated with signal 11, Segmentation fault.#0 &0x0018506a in memcpy () from /lib/tls/i686/cmov/libc.6从输出看出,同4.2.1中一样的段错误信息。5、完成调试后,输入quit命令退出gdb:(gdb) quit4.3.2 适用场景1、适合于在实际生成环境下调试程序的段错误(即在不用重新发生段错误的情况下重现段错误)。2、当程序很复杂,core文件相当大时,该方法不可用。4.4 使用objdump4.4.1 调试步骤1、使用dmesg命令,找到最近发生的段错误输出信息::~/segfault$ dmesg... ...[] segfault3[3320]: segfault at 80484e0 ip 0018506a sp bfc1cd6c error 7 in libc-2.10.1.so[;13e000]其中,对我们接下来的调试过程有用的是发生段错误的地址:80484e0和指令指针地址:0018506a。2、使用objdump生成二进制的相关信息,重定向到文件中::~/segfault$ objdump -d ./segfault3 & segfault3Dump其中,生成的segfault3Dump文件中包含了二进制文件的segfault3的汇编代码。3、在segfault3Dump文件中查找发生段错误的地址::~/segfault$ grep -n -A 10 -B 10 &80484e0& ./segfault3Dump&121- 80483df: & &ff d0 & & & & & & & & & &call & *%eax122- 80483e1: & &c9 & & & & & & & & & & & leave &123- 80483e2: & &c3 & & & & & & & & & & & ret & &124- 80483e3: & &90 & & & & & & & & & & & nop125-126- &main&:127- 80483e4: & &55 & & & & & & & & & & & push & %ebp128- 80483e5: & &89 e5 & & & & & & & & & &mov & &%esp,%ebp129- 80483e7: & &83 e4 f0 & & & & & & & & and & &$0xfffffff0,%esp130- 80483ea: & &83 ec 20 & & & & & & & & sub & &$0x20,%esp131: 80483ed: & &c7 44 24 1c e0 84 04 & & movl & $0xx1c(%esp)132- 80483f4: & &08&133- 80483f5: & &b8 e5 84 04 08 & & & & & mov & &$0x80484e5,%eax134- 80483fa: & &c7 44 24 08 05 00 00 & & movl & $0x5,0x8(%esp)135- 8048401: & &00&136- 8048402: & &89 44 24 04 & & & & & & &mov & &%eax,0x4(%esp)137- 8048406: & &8b 44 24 1c & & & & & & &mov & &0x1c(%esp),%eax138- 804840a: & &89 04 24 & & & & & & & & mov & &%eax,(%esp)139- 804840d: & &e8 0a ff ff ff & & & & & call & 804831c &&140- 8048412: & &c9 & & & & & & & & & & & leave &141- 8048413: & &c3 & & & & & & & & & & & ret & &通过对以上汇编代码分析,得知段错误发生main函数,对应的汇编指令是movl $0xx1c(%esp),接下来打开程序的源码,找到汇编指令对应的源码,也就定位到段错误了。4.4.2 适用场景1、不需要-g参数编译,不需要借助于core文件,但需要有一定的汇编语言基础。2、如果使用了gcc编译优化参数(-O1,-O2,-O3)的话,生成的汇编指令将会被优化,使得调试过程有些难度。4.5 使用catchsegvcatchsegv命令专门用来扑获段错误,它通过动态加载器(ld-linux.so)的预加载机制(PRELOAD)把一个事先写好的库(/lib/libSegFault.so)加载上,用于捕捉断错误的出错信息。:~/segfault$ catchsegv ./segfault3Segmentation fault (core dumped)*** Segmentation faultRegister dump:&EAX:
& EBX: 00fb3ff4 & ECX:
& EDX: &ESI:
& EBP: bfb7ad38 & ESP: bfb7ad0c&EIP: 00ee806a & EFLAGS: &CS: 0073 & DS: 007b & ES: 007b & FS: 0000 & GS: 0033 & SS: 007b&Trap: 0000000e & Error:
& OldMask: &ESP/signal: bfb7ad0c & CR2: Backtrace:/lib/libSegFault.so[0x3b606f]??:0(??)[0xc76400]/lib/tls/i686/cmov/libc.so.6(__libc_start_main&#43;0xe6)[0xe89b56]/build/buildd/eglibc-2.10.1/csu/../sysdeps/i386/elf/start.S:122(_start)[0x8048351]Memory map:73000 r-xp :01 157 /lib/ld-2.10.1.so74000 r--p :01 157 /lib/ld-2.10.1.so75000 rw-p :01 157 /lib/ld-2.10.1.so003b0 r-xp :01 13105 /lib/libSegFault.so003b0 r--p :01 13105 /lib/libSegFault.so003b0 rw-p :01 13105 /lib/libSegFault.so00c00 r-xp :00 0 [vdso]00e0d000-00e29000 r-xp :01 4817 /lib/libgcc_s.so.100ea000 r--p :01 4817 /lib/libgcc_s.so.100e2a000-00e2b000 rw-p :01 4817 /lib/libgcc_s.so.100e00 r-xp :01 1800 /lib/tls/i686/cmov/libc-2.10.1.so00fb00 ---p :01 1800 /lib/tls/i686/cmov/libc-2.10.1.so00fb00 r--p :01 1800 /lib/tls/i686/cmov/libc-2.10.1.so00fb00 rw-p :01 1800 /lib/tls/i686/cmov/libc-2.10.1.so00fb00 rw-p :00 049000 r-xp :01 303895 /home/panfeng/segfault/segfault04a000 r--p :01 303895 /home/panfeng/segfault/segfault04b000 rw-p :01 303895 /home/panfeng/segfault/segfault457000 rw-p :00 0 [heap]b78cf000-b78d1000 rw-p :00 0b78df000-b78e1000 rw-p :00 0bfb67000-bfb7c000 rw-p :00 0 [stack]5. 一些注意事项1、出现段错误时,首先应该想到段错误的定义,从它出发考虑引发错误的原因。2、在使用指针时,定义了指针后记得初始化指针,在使用的时候记得判断是否为NULL。3、在使用数组时,注意数组是否被初始化,数组下标是否越界,数组元素是否存在等。4、在访问变量时,注意变量所占地址空间是否已经被程序释放掉。5、在处理变量时,注意变量的&#26684;式控制是否合理等。6. 参考资料列表1、/p-.html2、http://blog.chinaunix.net/space.php?uid=317451&do=blog&id=92412
(责任编辑:联盟电脑)
更多相关资讯
1、LVS的定义? LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集.....
【联盟电脑】部分内容自于互联网,其言论不代表本站观点,若本站侵犯到您的版权,请与站长联系,我们将在第一时间核实并删除!
版权所有 & 【联盟电脑】 | 专注分享有价值、实用的电脑技术和知识
Copyright &
All rights reserved. 京ICP备号

我要回帖

更多关于 找出错误版本号 的文章

 

随机推荐