首页 > 系统相关 >linux上编译release并剥离调试信息

linux上编译release并剥离调试信息

时间:2024-03-17 22:11:48浏览次数:19  
标签:EXE 编译 debug test 调试信息 linux release foo

使用 objcopy:

1转载出处:

原文作者:不插电码农

本文讲的是不编译完全release的可执行文件,而是使用cmake的RelWithDebugInfo(附加调试信息的编译,它的效果下面会说明)或者Debug编译也可以生成release版本的可执行文件进行调试.

详细的 cmake 使用会在下一篇文章里讲.

这里先记下Debug, Release 和 RelWithDebugInfo的区别(对比我手上的gcc 4.8.2编译出的不同版本得出的结论)

Debug 等同于 -O0 -g 编译选项, 不优化代码, 附加调试信息
Release 等同于 -O3 编译选项, 最大化优化代码, 但不包含调试信息
RelWithDebugInfo 等同于 -O2 -g 编译选项, 中等程度优化代码, 并且包含调试信息.
可以自定义使用-O3 -g 的编译选项,来生成最接近Release的代码(至于-ggdb的选项,加了以后二进制只大了8个字节,目测无所谓)

下面的方法只对-g编译有效,方法有两种.

man手册里推荐的方法

objcopy –only-keep-debug foo foo.dbg 把调试信息(即debug section)dump到单独的文件里.
objcopy –strip-debug foo 这里只剔除调试信息,符号信息仍保留(用户依然可以用nm查看到各种函数符号,我推荐用–strip-all,连同符号信息一起删除,生成的可执行文件更小,不影响调试)
objcopy –add-gnu-debuglink=foo.dbg foo 为foo添加.gnu-debuglink section, 这个会让二进制增加近100字节的样子.
这样分离了Debug Section后,就可以单独分发release版本的foo,调试时只需讲foo.dbg放在和foo同一目录下即可直接gdb foo进行调试.
如果不希望Release的最终二进制文件包含.gnu-debuglink段,那么可以直接省略第三步,且当成另一种方法,方便叙述.

同一
strip foo 这个效果等同于objcopy –strip-all foo,剔除所有符号和调试信息, 即为release版本.
方法二所不同的调试方法是需先加载dbg文件, gdb foo.dbg, 然后attach(或者exec)到foo进程,这样不要求.dbg和执行程序在同一个目录下,并且适合调试已经启动的进程,例如服务器.

2 测试

测试demo:CMakeLists.txt

cmake_minimum_required(VERSION 3.5) 
 
# set the project name 
project(test_EXE) 
 
SET(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_C_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 -DNDEBUG")
set(CMAKE_C_FLAGS_RELEASE "-g -O3 -DNDEBUG")

MESSAGE("Build type: " ${CMAKE_BUILD_TYPE})
 
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

add_executable(test_EXE
test.cpp 
)
add_custom_command(TARGET test_EXE
    POST_BUILD
    COMMAND objcopy --only-keep-debug ${EXECUTABLE_OUTPUT_PATH}/test_EXE  ${EXECUTABLE_OUTPUT_PATH}/test_EXE.debug
    COMMAND objcopy --strip-all ${EXECUTABLE_OUTPUT_PATH}/test_EXE
    COMMAND objcopy --add-gnu-debuglink=${EXECUTABLE_OUTPUT_PATH}/test_EXE.debug ${EXECUTABLE_OUTPUT_PATH}/test_EXE
     COMMENT "**** test cmake command: add_custom_command"
)

# 添加自定义目标,以便在构建过程中执行自定义命令
install(FILES ${EXECUTABLE_OUTPUT_PATH}/test_EXE.debug DESTINATION ${EXECUTABLE_OUTPUT_PATH})

 
#include <stdio.h>
#include <iostream>
#include <chrono>
#include <thread>
void PrintInfo()
{
    printf("load fun print info..........\n");
    
}

int addfun(int a ,int b)
{
    printf("will run a+b:%d\n",(a+b));
    return a+b;
    
}

int main(void)
{
    int a=3,b=5;
    PrintInfo();
    int c = addfun(a,b);
    printf("-----print a+b ok\n");
    while(1)
         {
    static int c =0;
                      static int d =1;
                      addfun(c,d);
    c++;
    d++; 
                     std::this_thread::sleep_for(std::chrono::seconds(1)); //Ãë    
           }
    return 0;
}

测试的时候使用cmake -DCMAKE_BUILD_TYPE=Release生成Makefile,然后输入make命令生成exe;注意这些操作要在root下,否则会出现无法调试,如continue的时候出现 the program is not running等;

自测程序如果top 找不到Pid,请用pidof命令查找 

编译exe:

 sudo 运行:

 我们先看没有符号表的,就是在文件夹中只有test_EXE,没有调试debug文件的:

可以看到pidof test_EXE,然后gdb attach pid后,打断点根本不会停;

 然后我们把刚刚一起编译的test_EXE.debug放到同一个目录下(不用重启程序,因为实际情况下,一般都是项目运行中如果出错,你重启程序编译debug调试,或者重启添加debug符号,现象有可能就无法出现了,我们就是要在出错的release版本下,添加符号直接调试)

 调试:

 综上就可以同时编译release以及剥离出来的debug调试信息,如果现场遇到需要调试的情况就可以直接把debug文件放进运行目录,在线调试,而不必停止程序的运行;

标签:EXE,编译,debug,test,调试信息,linux,release,foo
From: https://www.cnblogs.com/8335IT/p/18079295

相关文章

  • linux libc.so.6软链接错误 导致ls等基础命令无法使用,系统无法登录
    转:linuxlibc.so.6软链接错误导致ls等基础命令无法使用_error:/lib64/libpthread.so.0:symbol__libc_dl_er-CSDN博客目录 一、背景说明二、处置步骤1、故障状态2、通过ls命令tab补全键查看文件列表3、查看glibc版本4、重建libc.so.6的软链接5、ssh远程连接报错6、......
  • Linux:系统初始化,内核优化,性能优化(1)
    我们安装好了一个服务器之后,一定要对他的系统,内核,性能一系列进行一个优化,否则当大并发的情况下很可能出现问题,我把要优化的东西直接罗列出来并介绍,后期可以直接编写一个脚本拿到服务器上直接用就行        设置时区我们在中国,一般选择的都是亚洲上海,在装服务器的时......
  • 常用conda和Linux命令
    常用conda命令condalist#查看安装的包condainstallxxx=版本号#安装指定版本号的包condauninstallxxx#删除某个包condaenvlist#查看所有环境condaactivateenv_name#进入名为env_name的环境condacreate--nameenv_namepython=3.5#创建指定python版......
  • BcLinux-Redis-集群(cluster)模式安装配置
    IP:192.168.0.28081、8082IP:192.168.0.3 8081、8082IP:192.168.0.4 8081、80821、三个节点同样操作[root@server-1setup]#yuminstalltcl或者:wgethttp://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gztarxzvftcl8.6.1-src.tar.gz-C/home/local/cd/home/loc......
  • 使用linux三剑客取ip地址
    1,使用awk命令ifconfigens33(先试用ifconfig来查看IP地址在几行几列或者使用ip-a也可以)可以看到IP地址在第二列第二行,接下来使用awk命令来取出IP地址ifconfigens33|awk'{print$2}'|awk'NR==2{print$0}'(print$2打印出第二列)(print$0打印出一整行内容)(NR等......
  • Linux第81步_使用“互斥体”实现“互斥访问”共享资源
    1、创建MyMutexLED目录输入“cd/home/zgq/linux/Linux_Drivers/回车”切换到“/home/zgq/linux/Linux_Drivers/”目录输入“mkdirMyMutexLED回车”,创建“MyMutexLED”目录输入“ls回车”查看“/home/zgq/linux/Linux_Drivers/”目录下的文件和文件夹2、添加gpio_led节点......
  • C语言之Linux环境下学习(一)
    C语言目录C语言学习前言一、了解Linux环境二、Linux环境下编译helloworld.c1.初识Linux指令1.ls:查看当前路径内容2.cd:进入指定路径3.创建和删除文件夹:mkdir、rmdir4.创建文件:touch和gedit2.创建并编译helloworld.c文件前言创建Linux环境,并且在此环境中......
  • C语言之Linux环境下学习(三)
    本章节主要讲了数据类型、变量命名规则、运算符优先级。目录1.main函数2.注释:​编辑3.标准输入(scanf)和标准输出(printf)4.数据类型4.1整数型:4.2浮点型:5.运算符优先级6.字符常量7.运算符​编辑8.变量8.1全局变量局部变量1.main函数main函数是C语言程序的主......
  • 【Linux】linuxCNC+Qt+Opencascade+kdl+hal 实时6轴机器人控制器
    CNC机器人程序框架机器人模型笔记:debian重启后无法打开共享目录最新版搜狗输入法安装后不支持中文,需要安装旧版本的sogoupinyin_4.0.1.2800_x86_64.deb可用数控机器人在哪些领域应用有优势数控机器人在多个领域都展现出了显著的优势,特别是在需要高精度和......
  • Linux监控CPU和GPU
    监控显卡占用情况watch-n2nvidia-smicpupower安装sudoaptinstalllinux-tools-commonCPU实时频率查看watch-n1sudocpupowermonitor查看cpu频率watch-n0"cat/proc/cpuinfo|grep-imhz"查看cpu频率模式cpupowerfrequency-info查看当前所有CPU的信息su......