成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C開發中段錯誤的三種調試方法

開發 后端
之前我們有分享總線錯誤的例子:Linux軟件開發中,總線錯誤的坑?替大家先踩一步。

大家好,我是雜燴君。

嵌入式C開發,或多或少都遇到段錯誤(segmentation fault )。

段錯誤相比于總線錯誤,是一種更常見的錯誤。

段錯誤是怎么產生的呢?

段錯誤是因為訪問不可訪問的內存產生的。

下面是一些典型的段錯誤產生的原因:

  • 訪問不存在的內存地址
  • 訪問只讀的內存地址
  • 棧溢出
  • 內存越界
  • ……

段錯誤實例

1、實例1:訪問不存在的內存地址

#include <stdio.h>
int main(int argc, char **argv)
{
printf("==================segmentation fault test==================\n");
int *p = NULL;
*p = 1234;
return 0;
}

2、實例2:訪問只讀的內存地址

#include <stdio.h>
int main(int argc, char **argv)
{
printf("==================segmentation fault test1==================\n");
char *str = "hello";
str[0] = 'H';
return 0;
}

3、實例3:棧溢出

#include <stdio.h>
static void test(void)
{
char buf[1024 * 1024] = {0};
static int i = 0;
i++;
printf("i = %d\n", i);
test();
}
int main(int argc, char **argv)
{
printf("==================segmentation fault test2==================\n");
test();
return 0;
}

4、實例4:內存越界
#include <stdio.h>
int main(int argc, char **argv)
{
printf("==================segmentation fault test3==================\n");
static char arr[5] = {0, 1, 2, 3, 4};
printf("arr[10000] = %d\n", arr[10000]);
return 0;
}

段錯誤調試方法

從上面的幾個例子中,我們應該對段錯誤有了一定的認識,但實際項目中,實際中,段錯誤可能沒有上面的例子那么明顯看出。如果之前沒有這方面的經驗,可能一時半會也定位不到問題。下面分享段錯誤的3種調試方法供大家參考。

我們依舊使用例子來說明,例子:

#include <stdio.h>
static void func0(void)
{
printf("This is func0\n");
int *p = NULL;
*p = 1234;
}
static void func1(void)
{
printf("This is func1\n");
func0();
}
int main(int argc, char **argv)
{
printf("==================segmentation fault test4==================\n");
func1();
return 0;
}

1、gdb一步步運行

使用gdb調試,打一些斷點、按流程運行下去,運行到段錯誤的地方會直接提示報錯。

或者使用命令行直接gdb調試:

這里我們是在x86上運行,如果是定位arm嵌入式Linux程序,我們怎么做的?

同樣也是可以使用gdb的,可以參考我們之前分享的文章:VSCode+gdb+gdbserver遠程調試ARM程序

2、通過core文件

Linux下,一個程序崩潰時,它一般會在指定目錄下生成一個core文件。core文件僅僅是一個內存映象(同時加上調試信息),主要是用來調試的。

core文件可打開與關閉。相關命令:

ulimit -c   # 查看core文件是否打開
ulimit -c 0 # 禁止產生core文件
ulimit -c unlimited #設置core文件大小為不限制大小
ulimit -c 1024 #限制產生的core文件的大小不能超過1024KB

0代表關閉。下面我們打開它:

運行程序時,程序崩潰時,在程序目錄下會生成core文件,如:

調試core文件:

gdb test core

3、利用backtrace進行分析

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <execinfo.h>
void func0(void)
{
printf("This is func0\n");
int *p = NULL;
*p = 1234;
}
void func1(void)
{
printf("This is func1\n");
func0();
}
void func2(void)
{
printf("This is func2\n");
func1();
}
void dump(int signo)
{
void *array[100];
size_t size;
char **strings;
size = backtrace(array, 100);
strings = backtrace_symbols(array, size);
printf("Obtained %zd stacks.\n", size);
for(int i = 0; i < size; i++)
{
printf("%s\n", strings[i]);
}

free(strings);
exit(0);
}
int main(int argc, char **argv)
{
printf("==================segmentation fault test5==================\n");
signal(SIGSEGV, &dump);
func2();
return 0;
}

當程序發生段錯誤時,內核會向程序發送SIGSEGV信號。dump為SIGSEGV信號處理函數,其實現用到了execinfo.h里的兩個函數:

int backtrace(void **buffer,int size);
char ** backtrace_symbols (void *const *buffer, int size);

backtrace函數用于獲取當前線程的調用堆棧,獲取的信息將會被存放在buffer中,它是一個指針列表。參數 size 用來指定buffer中可以保存多少個void* 元素。函數返回值是實際獲取的指針個數,最大不超過size大小 在buffer中的指針實際是從堆棧中獲取的返回地址,每一個堆棧框架有一個返回地址。

backtrace_symbols將從backtrace函數獲取的信息轉化為一個字符串數組。參數buffer應該是從backtrace函數獲取的指針數組,size是該數組中的元素個數(backtrace的返回值)。函數返回值是一個指向字符串數組的指針,它的大小同buffer相同。

每個字符串包含了一個相對于buffer中對應元素的可打印信息。它包括函數名,函數的偏移地址,和實際的返回地址。注意:該函數的返回值是通過malloc函數申請的空間,因此調用者必須使用free函數來釋放指針。如果不能為字符串獲取足夠的空間函數的返回值將會為NULL。

以上就是本次介紹的三種定位段錯誤問題的方法,可以定位不同程度的問題。

責任編輯:龐桂玉 來源: C語言與C++編程
相關推薦

2009-10-14 14:37:56

調試.NET程序

2021-06-07 08:00:00

開發集成API

2009-09-08 10:37:57

C#遍歷CheckBo

2022-12-07 10:20:08

藍牙物聯網

2017-10-18 15:30:47

數據中心錯誤方法

2009-08-26 18:10:44

C# using的用法

2009-07-30 16:27:33

C#比較時間

2009-07-08 12:56:32

編寫Servlet

2019-08-30 17:24:41

microservic微服務

2009-08-20 17:30:02

C#連接字符串

2020-09-08 12:53:47

C++數據線程

2024-12-03 00:40:55

2009-08-06 15:26:18

C#異常類型

2022-05-30 07:07:35

Java監聽文件Java 8

2016-09-30 01:10:12

R語言聚類方法

2010-09-14 15:10:49

CSS注釋

2022-07-13 16:06:16

Python參數代碼

2011-04-18 15:32:45

游戲測試測試方法軟件測試

2009-12-11 18:49:39

預算編制博科資訊

2023-08-14 17:58:13

RequestHTTP請求
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人国产精品入口免费视频 | 国产精品视频久久久久 | 亚洲成人久久久 | 日韩精品在线一区 | 久久精品成人 | 久久91精品 | 国产精品福利一区二区三区 | 免费观看色 | 免费观看黄色一级片 | 91精品久久久久久久久久入口 | 国精产品一品二品国精在线观看 | 欧美日韩电影一区二区 | 天堂久久网| 免费的av网站 | 久草日韩 | 激情一区 | 欧美精品乱码99久久影院 | 国产精品久久 | av播播| 久久男人 | 国产91综合一区在线观看 | 一二三四在线视频观看社区 | 免费福利视频一区二区三区 | www.婷婷| 亚洲视频在线免费观看 | 久久精品一区二区 | 欧美成人精品在线 | 亚洲福利| 99这里只有精品视频 | 国产一区 | 中文字幕一区二区三区日韩精品 | 亚洲福利网站 | 亚洲国产一区视频 | 欧美精品在线一区 | 久久久精品久 | 亚洲欧美在线视频 | 在线视频一区二区三区 | av免费观看网站 | 在线看免费的a | 久久午夜视频 | 一区二区三区视频 |