core文件调试(gdb)

1 篇文章 0 订阅

目录

code文件配置

查看系统配置生成code文件大小

配置系统关闭生成core文件大小

临时: 终端输入ulimit -c unlimited

永久:

配置生产code文件名称和路径

gdb 调试code文件

简单代码测试:        

测试带动态库的程序

动态库程序

应用程序

执行

调试分析原因

执行gdb运行程序


运行linux时,我们可以设定程序在崩溃的时候生成code文件,便于我们查找程序崩溃产生的原因。

code文件配置

查看系统配置生成code文件大小

1 ulimit  -c/ulimit -a命令查看系统是否开启了这个功能

                                                                 图1

图1都显示为0,表示没有开启code文件的产生,即程序崩溃时,系统不会产生code文件 

                                                                 图2

图2都显示为unlimited,表示code文件大小不做限制,即程序崩溃时,系统会产生code代销不做限制

配置系统关闭生成core文件大小

临时: 终端输入ulimit -c unlimited

                                                                         图3

如图3,输入ulimit -c unlimited后再查询显示已经是unlimited。

备注:

a:ulimit是linux命令,用来限制每个用户可使用的资源,如CPU、内存、句柄等。

b: -c 当某些程序发生错误时,系统可能会将该程序在内存中的信息写成文件(除错用),这种文件就被称为核心文件(core file)。此为限制每个核心文件的最大容量

c: -c 后面接的是设置的大小。

永久:

在/etc/pfofile后面加上一行

ulimit -c unlimited 

修改完成之后指向source/etc/profile可以让配置立即生效

配置生产code文件名称和路径

设置pid作为文件扩展名

echo "1" > /proc/sys/kernel/core_uses_pid

控制core文件保存位置和文件名格式

echo "/root/test/gdb/core-%e-%p-%t" > /proc/sys/kernel/core_pattern

命名格式说明:

检查是否生效:

上面的设置大概只是暂时生效,永久生效需要在系统配置文件/etc/sysctl.conf中设置

kernel.core_uses_pid = 1

kernel.core_pattern = /corefile/core-%e-%p-%t

然后执行sysctl -p立即生效,检查是否生效:

查看输出是否为自己设置的路径

如果重启电脑之后还是无法生效,则需要再次执行sysctl -p

gdb 调试code文件

1:默认格式

gdb your_program core

2:如果你有一个core文件,确保它与你要调试的可执行文件相关联。如果core文件的名称不是默认的core,可以使用-c选项将其与可执行文件关联起来。例如:

gdb -c core your_program

或者

3:启动GDB调试会话:

gdb your_program

在GDB提示符下,使用以下命令来加载core文件:

core-file core

GDB会显示相关的调试信息并暂停在发生错误的位置。你可以使用常用的GDB命令来分析和调试代码

简单代码测试:        

test.cpp:

#include<iostream>
#include<stdlib.h>
using namespace std;


void testMemoryLeak()
{
    // int *p = (int *)malloc(1);
    int *p;


    
    *p = 10;
    cout<<"*p = "<<*p<<endl;
}

int main()
{   
    testMemoryLeak();
    return 0;
}

编译运行:编译要加上 -g

在/root/test/gdb 下面产生了一个名字为core-testgdb-199626-1688451085的core文件

gdb 调试code文件

 

 明确显示在程序的13行有段错误

测试带动态库的程序

动态库程序

文件目录

Makefile

MAKEFILE=Makefile
CC=/usr/bin/gcc
CXX=/usr/bin/g++

BIN=libtest.so
CFLAGS = -shared -fPIC

INCS=-I./ #头文件目录
SRCS:=$(wildcard *.cpp) #.cpp文件目录
COBJS:=$(SRCS:.cpp=.o)

all:$(BIN)

$(COBJS) : %.o: %.cpp
	$(CXX) -c $< -o $@ $(INCS) $(CFLAGS)

$(BIN):$(COBJS)
	$(CXX) -o $(BIN) $(COBJS) $(CFLAGS) 
	rm $(COBJS)

test.cpp

#include "test.h"
int addSum(const int a,const int b)
{
    return a+b;
}
void mySwap(int *pA,int *pB)
{
    int temp = *pA;
    *pA = *pB;
    *pB = temp;
}

test.h

#ifndef _TEST__H__
#define _TEST__H__
#include<iostream>
int addSum(const int a,const int b);
void mySwap(int *pA,int *pB);
#endif

编译当前目录下面生成libtest.so动态库

应用程序

main.cpp

#include "./../test.h"
#include <iostream>

int main()
{   
    int a =10;
    int b =20;
    std::cout<<"a = "<<a<<std::endl;
    std::cout<<"b = "<<b<<std::endl;

    mySwap(&a,&b);
    std::cout<<"a = "<<a<<std::endl;
    std::cout<<"b = "<<b<<std::endl;
    int *p1;
    int *p2;
    mySwap(p1,p2);
    return 0;
}

Makefile

MAKEFILE=Makefile
CC=/usr/bin/gcc
CXX=/usr/bin/g++

BIN=test
CFLAGS = -g -fPIC
LIBS=-L./../ -ltest

INCS=-I./../ #头文件目录
SRCS:=$(wildcard *.cpp) #.c文件目录
COBJS:=$(SRCS:.cpp=.o)

all:$(BIN)

$(COBJS) : %.o: %.cpp
	$(CXX) -c $< -o $@ $(INCS) $(CFLAGS)

$(BIN):$(COBJS)
	$(CXX) -o $(BIN) $(COBJS) $(CFLAGS) $(LIBS)
	rm $(COBJS)

clean:
	rm $(BIN) $(COBJS)

编译生成test执行文件

执行

产生了段错误。

调试分析原因

运行 gdb test ../../core-test-335980-1688968636

 显示程序在库libtest.so 的mySwap的调用产生了段错误。

查看bt

是在main.cpp的main函数的第15行调用了这个函数

产生这个段错误的原因是使用了空指针(指针传参没有进行参数校验就进行了使用)

执行gdb运行程序

配置环境变量 export LD_LIBRARY_PATH=/root/test/gdb/SO:$LD_LIBRARY_PATH

运行程序 gdb test

可以看到 在main.cpp的第15行调用了mySwap函数产生了段错误

备注:要是想看库的源码可以在编译库的时候加上-g

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值