天天看點

linux上一個經典的segmentation fault

廢話不多說,請看下面代碼:

#include<string>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
int version=1;

int main()
{
	char *testarry[3]={"a","b","c"};
	strcpy(testarry[2],"C");
	printf("%c",testarry[2][0]);
	printf("%s\n",testarry[2]);
	if(testarry[2][0])
	{
	printf("version:%d",1);
	}
	return 0;
}
           

編譯運作,segmentation fault 出現了。分析以上代碼,一眼看上去,似乎沒毛病,嘗試把下面語句去掉

strcpy(testarry[2],“C”);

竟然運作通過,也就說使用testarry[2][0]作為if判斷的标準,作為%c輸出都沒有問題。

那麼奇怪了啊,為什麼strcopy語句一加上就挂呢。搞出gdb來分析。

使用g++ main.cpp -g編譯得到a.out -g是為了得到符号表

過程如下:

[email protected]:~/testcplus$ gdb a.out

GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1

Copyright © 2016 Free Software Foundation, Inc.

License GPLv3+: 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 “x86_64-linux-gnu”.

Type “show configuration” for configuration details.

For bug reporting instructions, please see:

http://www.gnu.org/software/gdb/bugs/.

Find the GDB manual and other documentation resources online at:

http://www.gnu.org/software/gdb/documentation/.

For help, type “help”.

Type “apropos word” to search for commands related to “word”…

Reading symbols from a.out…done.

(gdb) list

1 #include

2 #include<stdio.h>

3 #include<unistd.h>

4 #include<string.h>

5

6 //#include “dervied.h”

7 int version=1;

8

9 int main()

10 {

(gdb) list

11 char *testarry[3]={“a”,“b”,“c”};

12 strcpy(testarry[2],“C”);

13 printf("%c",testarry[2][0]);

14 printf("%s\n",testarry[2]);

15 if(testarry[2][0])

16 {

17 printf(“version:%d”,1);

18 }

19 return 0;

20 }

(gdb) break 11

Breakpoint 1 at 0x40063d: file main.cpp, line 11.

(gdb) r

Starting program: /home/yuneec01/testcplus/a.out

Breakpoint 1, main () at main.cpp:11

11 char *testarry[3]={“a”,“b”,“c”};

(gdb) n

12 strcpy(testarry[2],“C”);

(gdb) n

Program received signal SIGSEGV, Segmentation fault.//這裡就挂了

0x0000000000400659 in main () at main.cpp:12

12 strcpy(,“C”);

(gdb) p testarry //果斷把testarry的打出來看看,看到testarry[2]的位址是0x400748

$1 = {0x400744 “a”, 0x400746 “b”, 0x400748 “c”}

也就是操作這個位址挂了

我們去read以下a.out看看

使用readelf -S a.out

找0x400748所在的段,如下:

[16] .rodata PROGBITS 0000000000400740 00000740

0000000000000015 0000000000000000 A 0 0 4

問題出現,此段為.rodata

strcpy把rodata當作目标字元串操作,setmentation fault是必然出現了。

以上給大家班門弄斧的展示了一次尋找segmentation fault根源的方法。水準有限,還望賜教。

謝謝

繼續閱讀