1.源文件与目标文件
源文件是指源代码文件.
目标文件是指源代码经过编译程序产生的能被cpu直接识别二进制代码. Windows下为.obj文件, Linux为.o文件
目标文件是源代码编译后但未进行链接的那些中间文件。
2.静态库与动态库(共享库)
静态库实际上就是简单的一个普通的目标文件的集合,一般来说习惯用“.a”作为文件的后缀.
静态库可以链接到程序中成为执行程序的一部分.
动态库(共享库)是在程序运行期间才加载到内存中, 可以被多个程序共享使用.
动态库在Linux下为.so文件, Windows下为.dll文件.
3.gcc与g++
gcc为C语言编译器,g++为C++语言编译器
gcc与g++用法相同。
(1)gcc与g++均是GNU下的编译器
(2)对于 *.c和*.cpp文件,gcc分别当做c和cpp文件编译(c和cpp的语法强度是不一样的)
(3)对于 *.c和*.cpp文件,g++则统一当做cpp文件编译
(4)使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL
(5)在用gcc编译c++文件时,为了能够使用STL,需要加参数 –lstdc++ ,但这并不代表 gcc –lstdc++ 和 g++等价,它们的区别不仅仅是这个
(6)gcc与g++的安装
CentOS: yum -y install gcc gcc-c++
或: yum -y groupinstall "Development Tools"
4.编译过程
gcc将源码编译成可执行文件的过程可以分解为4个步骤: 预处理(Preprocess)、编译(Compile)、汇编(Assembly)和链接(Link)
(1)预处理(Preprocess)
源代码文件(.c/.cpp)和相关头文件(.h/.hpp)被预处理器cpp预编译成.i文件(C++为.ii)
预处理命令为: gcc -E test.c -o test.i
或: g++ -E hello.cpp -o hello.ii
(2)编译(Compile)
编译过程就是把预处理完的文件进行一系列词法分析,语法分析,语义分析及优化后生成相应的汇编代码文件(.s)
编译的命令为: gcc -S test.i -o test.s
也可以直接从源文件编译为汇编文件: gcc -S test.c -o test.s
现在版本的GCC把预编译和编译两个步骤合并成一个步骤,由程序cc1来完成(C++为cc1plus)
gcc命令: gcc -S hello.cpp -o hello.s
g++命令: g++ -S hello.cpp -o hello.s
(3)汇编(Assembly)
汇编就是将汇编代码转变成机器可以执行的命令,生成目标文件(.o),汇编器as根据汇编指令和机器指令的对照表一一翻译即可完成
汇编的命令为: gcc –c test.s –o test.o
或者直接从源文件输出目标文件: gcc –c test.c –o test.o
g++命令: g++ -c hello.cpp -o hello.o
(4)链接(Link)
链接就是链接器ld将各个目标文件组装在一起,解决符号依赖,库依赖关系,并生成可执行文件。
一般使用ld命令来链接, 而collect2是ld命令的一个封装, gcc通常使用collect2来链接.
可用g++ -v test.o 查看可用于Link test.o的命令. 链接需要依赖很多系统库和相关的目标文件,命令比较长.
g++命令: g++ hello.o -o hello.exe (不带任何参数会直接执行 预处理,编译,汇编,链接 4个流程,并生成可执行文件)
或直接指定hello.cpp: g++ hello.cpp -o hello.exe
(5)参考
Linux下编译、链接和装载: https://blog.csdn.net/wdsfup/article/details/78411237
5.gdb
(1)简介
GDB是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。
GDB中的命令固然很多,但我们只需掌握其中十个左右的命令,就大致可以完成日常的基本的程序调试工作。
官网:https://www.gnu.org/software/gdb/
(2)调试用例,将以下代码保存为gdbtest.c
#include <stdio.h>
int nGlobalVar = 0;
int tempFunction(int a, int b)
{
printf("tempFunction is called, a = %d, b = %d /n", a, b);
return (a + b);
}
int main()
{
int n;
n = 1;
n++;
n--;
nGlobalVar += 100;
nGlobalVar -= 12;
printf("n = %d, nGlobalVar = %d /n", n, nGlobalVar);
n = tempFunction(1, 2);
printf("n = %d", n);
return 0;
}
(3)编译
要使用gdb调试,需要在gcc编译时添加-g参数.
编译命令: gcc gdbtest.c -o gdbtest -g
(4)调试
在命令行输入gdb进入gdb调试
file gdbtest
gdb命令表格
命令缩写功能
runr运行,遇到断点停止
continuec继续执行,到下一个断点处(或运行结束)
nextn单步调试(不进入函数体)
steps单步调试(有函数则进入函数体)
until运行程序直到退出循环体
until+行号运行至某行,不仅仅用来跳出循环
更多命令参考: https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/gdb.html#
(5)linux 启用core dump文件
程序崩溃时, 会保存一个core dump文件, 默认情况下并不保存.
启用core dump方法:
执行ulimit -c, 如果输出结果是0, 说明core dump是关闭的.
执行ulimit -c unlimited 来开启core dump功能, 该命令只对当前terminal有效
参考:https://blog.csdn.net/K346K346/article/details/48344263
(6)windows启用core dump文件
[1]运行REGEDIT.EXE 找到 “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps”
[2]如果没有LocalDumps,则新建一个key为LocalDumps
[3]在LocalDumps下面, 创建DumpFolder(类型String Value), 值为C:\test\dump, 即dump文件保存在C:\test\dump
[4]在LocalDumps下面, 创建DumpCount(类型DWORD Value), 值为a ,即最多10个dump文件
[5]在LocalDumps下面, 创建DumpType(类型DWORD Value), 值为1 即MiniDump
(7)windbg
可使用windbg查看Windows上的.dump文件, 用 !analyze -v 来分析 ,在STACK_TEXT段查看stacktrace信息
(8)ffmpeg编译调试版本
添加configure参数: --enable-debug=3 与 --disable-optimizations 与 --disable-stripping
参考: https://www.cnblogs.com/my_life/articles/6693948.html
(9)参考
gdb十分钟教程:https://blog.csdn.net/liigo/article/details/582231
gdb详解:https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/gdb.html#
6.windbg
(1)简介
WinDbg是Microsoft Windows上的多用途调试器,可从微软网站上免费下载安装使用。可用于调试用户态下的应用程序、驱动程序,以及核心态下的操作系统自身,以及对Core Dump文件的分析 。该软件是GUI界面.
WinDbg可以装入DLL扩展以增强调试器的命令。扩展命令总是以!为前缀。WinDbg的扩展命令总是以!为前缀
WinDbg单独安装包下载:https://blog.csdn.net/counsellor/article/details/80816583
(2)WinDBG包括3类命令:标准命令、元命令、扩展命令
标准命令提供适用于所有调试目标的基本调试功能,都是WinDBGM调试器内部实现的,不需要加载任何扩展模块。 标准命令第一个字符不分大小写,第二个字符可能区分。
元命令是内建在调试器引擎或者WinDBG程序文件中的。所有元命令都以一个点.开始,所以也被称为点命令。
扩展命令是是现在动态加载的扩展模块中的。扩展命令,以叹号!开始,叹号在英文中读作bang,因此扩展命令也被称为Bang Command
扩展命令的完整格式是
![扩展模块名].<扩展命令名> [参数]
扩展模块名可以省略。
WinDBG命令手册:https://www.cnblogs.com/gaochundong/p/windbg_cheat_sheet.html
WinDBG命令: https://www.cnblogs.com/kekec/archive/2012/12/02/2798020.html
(3)设置symbol
执行以下命令:
.sympath C:\test\symbols_my;SRV*C:\test\symbols_cache*http://msdl.microsoft.com/download/symbols
C:\test\symbols_my 代表自己的symbol路径,可以将pdb放在该目录, C:\test\symbols_cache 代表下载缓存的symbols
设置完.symbpath, 可以执行.reload来加载symbols