首页 > 系统相关 >Linux下C++程序瘦身

Linux下C++程序瘦身

时间:2024-10-13 10:47:44浏览次数:7  
标签:瘦身 程序 C++ gdb 调试信息 Linux debug main 调试

目录

一.前言

我们知道,C++程序如果带着调试信息的话会比较大,所以一般发布版本都会去掉调试信息,但是我们又希望如果程序崩溃了可以使用core转储文件进行调试,如果不带调试信息就不能方便的进行调试,那要怎么办呢,这篇文章会简单的讨论一下。

二.如何瘦身

我们知道C++程序瘦身的办法就是去掉调试信息。

先看代码

//main.cpp

#include<iostream>

void Func(void)
{
	int* p = nullptr;
	int a = *p;
	std::cout << a << std::endl;
}

int main(int argc, char* argv[])
{
	Func();

	return 0;
}

我们可以看到函数Func()中使用了空指针,这样就会导致程序崩溃。我们使用这个代码生成main程序,然后执行main生成core转储文件,然后利用core转储文件进行调试。

这里要注意的是可能需要先开启生成core转储文件(比如执行命令ulimit -c unlimited),具体这篇文章不展开了。

我们使用-g选项生成一个带调试信息的main,然后看下大小。

在这里插入图片描述

这个时候我们执行命令readelf -S ./main看一下section-headers信息的话,会发现调试信息都包含在内。

在这里插入图片描述

执行main程序生成core转储文件,使用gdb调试。

在这里插入图片描述

我们可以看到gdb调试的时候可以定位到具体问题。

现在使用命令strip --strip-debug ./main去掉main程序里的debug信息(和不开启-g选项生成的main程序基本一样),然后看下大小。

在这里插入图片描述

可以发现main程序的大小下降了很多。

这个时候如果看下section-headers信息,会发现debug信息去掉了,但是符号表信息还包含。

重新执行main程序生成core转储文件,使用gdb调试。

在这里插入图片描述

我们可以看到这个时候gdb调试虽然可以定位问题,但是不够具体。

现在使用命令strip --strip-all ./main去掉所有调试信息,这个时候main程序的大小还会下降的,而且如果看下section-headers信息,会发现符号表信息也去掉了。然后重新执行main程序生成core转储文件,使用gdb调试。

在这里插入图片描述

我们可以看到这个时候gdb调试基本上不能定位问题了。

所以这个时候就是程序瘦身完成了,但是却不能使用core转储文件调试了,我们看下怎么解决。

我们使用-g选项重新生成一个带调试信息的main程序,然后看下大小。

在这里插入图片描述

然后执行命令eu-strip ./main -f ./main.debug去掉main程序的调试信息并且生成调试信息文件main.debug。这个时候main程序的大小以及section-headers的信息和执行命令strip --strip-all ./main基本是一样的(section-headers的信息稍微不同,因为需要记录生成的调试信息文件)。

在这里插入图片描述

重新执行main程序生成core转储文件,使用gdb调试。

在这里插入图片描述

我们可以看到这个时候使用gdb调试可以定位到具体的问题,而且可以看到gdb调试的时候读取了调试文件main.debug。

这样我们就可以只发布main程序,然后备份main.debug,在需要调试的时候拿到main.debug就可以了。这样就可以既给程序瘦了身,还不影响调试。

三.如何读取调试信息文件

使用gdb调试的时候怎么读取调试信息文件呢,我们讨论一下。

gdb调试的时候会在同级目录下读取记录里的调试信息文件,也会在其他的一些目录读取,可以使用命令show debug-file-directory查看。

在这里插入图片描述

也可以在调试的时候指定需要读取的调试信息文件。

我们给main.debug改个名,重新执行main程序生成core转储文件,使用gdb调试。

在这里插入图片描述

我们可以看到这个时候gdb调试基本上不能定位问题了,因为gdb读取不到调试信息文件main.debug。

这个时候我们可以使用symbol-file指定读取调试信息文件。

在这里插入图片描述

这样也可以定位到问题。

启动gdb调试的时候也可以直接指定,而且这样调试还会方便一些。

在这里插入图片描述

四.其他

eu-strip可以使用命令apt install elfutils进行安装。

标签:瘦身,程序,C++,gdb,调试信息,Linux,debug,main,调试
From: https://blog.csdn.net/2401_85919417/article/details/142737122

相关文章

  • 高中生学习c/c++指导
    一、c与c++关系参考图示:可见,c与c++的基本部分是相同的,会有一些小区别,不妨一起学。DEV-C++能支持C++和C语言编程二、学习资料网站介绍1、C语言初阶——手把手教零基础/新手入门2、C++教程从入门到实战3、C++从0到1入门编程......
  • 25个Linux系统性能调优技巧
    大家好,我是V哥。Linux系统性能调优是一个多层次的过程,涉及内核参数调整、硬件配置优化、应用程序调整等多个方面。以下是25个详细的Linux系统性能调优技巧,帮助你提高系统的整体性能。1.调整swappiness参数技巧:减少系统对交换分区的依赖,提升内存使用效率。操作:将/proc/s......
  • Springboot在线学习辅导管理系统--49101(免费领源码)可做计算机毕业设计JAVA、PHP、爬虫
    摘 要信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对在线学习辅导管理系统等问题,对在线学习辅导管理系统进行研究分析,然后开发设计出在线学习辅......
  • Springboot一个小说阅读APP的设计与实现--48151(免费领源码)可做计算机毕业设计JAVA、PH
    摘 要大数据时代下,数据呈爆炸式地增长。为了迎合信息化时代的潮流和信息化安全的要求,利用互联网服务于其他行业,促进生产,已经是成为一种势不可挡的趋势。在小说在线阅读的需求下,开发一款小说阅读APP,将复杂的系统进行拆分,能够实现对需求的变化快速响应、系统稳定性的保障,能保......
  • 基于SaaS的小区物业管理系统设计与实现--47357(免费领源码)可做计算机毕业设计JAVA、PHP
    摘 要本论文主要论述了如何使用SpringBoot开发一个基于SaaS的小区物业管理系统小程序,本系统将严格按照软件开发流程进行各个阶段的工作,面向对象编程思想进行项目开发。在引言中,作者将论述小区物业管理系统小程序的当前背景以及系统开发的目的,后续章节将严格按照软件开发流程......
  • 小米平板5(nabu)安装 HyperOS + Arch Linux 双系统
    小米平板5(nabu)安装HyperOS+ArchLinux双系统资源准备(TODO)HyperOS系统本体进入BootloaderUotan工具箱中WiredFlash->MoreFlash->XiaomiScript选择Hyper_OS_1.1.5.0.VNXCNXM.BETA_安卓15/nabu_XiaomiPad5_OS1.1.5.0.VNXCNXM.BETA_15.0_By_mytiantian/flash_all.sh......
  • 嵌入式Linux系统磁盘空间问题
    问题描述:我的系统板是stm32mp157,属于mpu,搭载了嵌入式Linux系统,我将系统通过STM32CubeProgrammer烧录在了一张32g的sd卡上,可是系统烧录完毕启动板子后,使用命令df-h查看发现磁盘空间只有1个多g,如下图上网查看,问题可能出在我的系统是由buildroot进行构建的,某些嵌入式系统的构......
  • 每日OJ题_牛客_比那名居的桃子_滑动窗口/前缀和_C++_Java
    目录牛客_比那名居的桃子_滑动窗口/前缀和题目解析C++代码Java代码牛客_比那名居的桃子_滑动窗口/前缀和比那名居的桃子(nowcoder.com)描述:        小红有一天看到了一只桃子,由于桃子看上去就很好吃,小红很想把它吃掉。已知吃下桃子后,每天可以获得ai​的......
  • 从0开始的vscode安装及环境配置教程(C/C++)Windows系统
    1.vscode简介VSCode是微软出的一款轻量级编辑器,它本身只是一款文本编辑器而已,并不是一个集成开发环境(IDE),几乎所有功能都是以插件扩展的形式所存在的。因此,我们想用它编程,不只是把vscode下载下来就行,还需要安装对应编程语言的扩展以及相应的编译器。2.安装vscode进入vscode......
  • C++中比较方便的几个有关字符串的函数
    以下是一些个人总结的C++中对新手来说比较方便使用的几个有关字符串的函数。注意,说的是字符串而不是字符数组。如果有其他,欢迎在评论区留言。1.getline(),这个函数可以输入一行字符串,通常情况下,这个函数的使用通常如下://getline(cin,字符串名);     注意:getline()的......