日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

段错误产生原因及简单的调试方法

發布時間:2023/12/10 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 段错误产生原因及简单的调试方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考:段錯誤產生原因及簡單的調試方法
作者:編程那些年
網址:https://mp.weixin.qq.com/s/KP9ZFn71CO_vB2I4igZLMA

段錯誤產生原因

1.訪問不存在的內存地址

如下面代碼,ptr沒有申請空間就直接拷貝數據:

#include <stdio.h> #include <string.h> #include <stdlib.h>int main(int argc, char *argv[]) {char *ptr = NULL;//This is the wrong implementation:strncpy(ptr, "abc", 3);//ptr沒有申請空間就直接使用//The right way://ptr = (char *)malloc(sizeof(char) * 10);//memset(ptr, 0, 10);//strncpy(ptr, "abc", 3);return 0; }

2.訪問只讀的內存地址

錯誤做法:往字符串常量空間拷貝新的數據

#include <stdlib.h> #include <stdio.h> #include <string.h>int main(int argc, char *argv[]) {char *ptr = "test";strcpy(ptr, "TEST1");return 0; }

3.訪問系統保護的內存地址

如:

#include <stdio.h>int main(int argc, char *argv[]) {int *ptr = (int *)0;*ptr = 100;return 0; }

4.棧溢出

如:

#include <stdlib.h> #include <stdio.h> #include <string.h>int main(int argc, char *argv[]) {main(argc, argv); }

初學時兩種常用的段錯誤調試方法

1.使用printf輸出調試信息

這個是看似最簡單但往往很多情況下是十分有效的調試方式,也許可以說是程序員用的最多的調試方式。簡單來說,就是在程序的重要代碼附近加上printf輸出信息,這樣可以跟蹤并打印出段錯誤在代碼中最可能出現的位置。

使用案例:
以下面這段錯誤代碼為例:

#include <stdio.h> #include <string.h> #include <stdlib.h>int main(int argc, char *argv[]) {char *ptr = NULL;//This is the wrong implementation:strncpy(ptr, "abc", 3);//ptr沒有申請空間就直接使用return 0; }

可以在代碼中添加printf調試信息:

#include <stdio.h> #include <string.h> #include <stdlib.h>int main(int argc, char *argv[]) {printf("line:%d\n", __LINE__); //單純打印代碼行數char *ptr = NULL;//This is the wrong implementation:printf("line:%d\n", __LINE__); //單純打印代碼行數strncpy(ptr, "abc", 3);//ptr沒有申請空間就直接使用printf("line:%d\n", __LINE__); //單純打印代碼行數return 0; }

編譯運行后,會有如下輸出:

line:7 line:10 Segmentation fault (core dumped)

通過日志信息,就可以看到strncpy(ptr, “abc”, 3);語句沒有被執行,我們就可以根據定位到的位置來排除ptr是否是未分配空間或者分配的空間不足引發的問題

2.使用gcc和gdb

調試步驟:

1、為了能夠使用gdb調試程序,在編譯階段加上-g參數,還是以下面這段錯誤代碼為例:

#include <stdio.h> #include <string.h> #include <stdlib.h>int main(int argc, char *argv[]) {char *ptr = NULL;//This is the wrong implementation:strncpy(ptr, "abc", 3);//ptr沒有申請空間就直接使用return 0; }

編譯代碼添加-g選項

gcc -g -o test test.c

編譯出test程序,然后用gdb調試:

linux@linux:~/test$ gdb ./test GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git Copyright (C) 2018 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 ./test...done. (gdb) r Starting program: /home/linux/test/test Program received signal SIGSEGV, Segmentation fault. 0x0000555555554611 in main (argc=1, argv=0x7fffffffe528) at test.c:9 9 strncpy(ptr, "abc", 3);//ptr沒有申請空間就直接使用 (gdb) quit A debugging session is active.Inferior 1 [process 15829] will be killed.Quit anyway? (y or n) y

從輸出看出,程序到SIGSEGV信號,觸發段錯誤,并提示地址0x0000555555554611以及代碼第9行出錯。

當然,還有利用core文件和gdb配置配合調試、使用objdump以及catchsegv命令的其他更為復雜的調試手段,這里就不展開講。

總結

以上是生活随笔為你收集整理的段错误产生原因及简单的调试方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。