目录
code文件配置
查看系统配置生成code文件大小
配置系统关闭生成core文件大小
临时: 终端输入ulimit -c unlimited
永久:
配置生产code文件名称和路径
gdb 调试code文件
简单代码测试:
测试带动态库的程序
动态库程序
应用程序
执行
调试分析原因
执行gdb运行程序
运行linux时,我们可以设定程序在崩溃的时候生成code文件,便于我们查找程序崩溃产生的原因。
1 ulimit -c/ulimit -a命令查看系统是否开启了这个功能
图1
图1都显示为0,表示没有开启code文件的产生,即程序崩溃时,系统不会产生code文件
图2
图2都显示为unlimited,表示code文件大小不做限制,即程序崩溃时,系统会产生code代销不做限制
图3
如图3,输入ulimit -c unlimited后再查询显示已经是unlimited。
备注:
a:ulimit是linux命令,用来限制每个用户可使用的资源,如CPU、内存、句柄等。
b: -c
当某些程序发生错误时,系统可能会将该程序在内存中的信息写成文件(除错用),这种文件就被称为核心文件(core file)。此为限制每个核心文件的最大容量
c: -c 后面接的是设置的大小。
在/etc/pfofile后面加上一行
ulimit -c unlimited
修改完成之后指向source/etc/profile可以让配置立即生效
设置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
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
#include
using namespace std;
void testMemoryLeak()
{
// int *p = (int *)malloc(1);
int *p;
*p = 10;
cout<<"*p = "<<*p<
编译运行:编译要加上 -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
int addSum(const int a,const int b);
void mySwap(int *pA,int *pB);
#endif
编译当前目录下面生成libtest.so动态库
main.cpp
#include "./../test.h"
#include
int main()
{
int a =10;
int b =20;
std::cout<<"a = "<
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行调用了这个函数
产生这个段错误的原因是使用了空指针(指针传参没有进行参数校验就进行了使用)
配置环境变量 export LD_LIBRARY_PATH=/root/test/gdb/SO:$LD_LIBRARY_PATH
运行程序 gdb test
可以看到 在main.cpp的第15行调用了mySwap函数产生了段错误
备注:要是想看库的源码可以在编译库的时候加上-g