- 文件路径搜索
cd test/gdbtest 可操控当前路径的直接文件
ls 显示当前路径的直接文件
- Gedit 文本编辑器
touch test.c 创建文本
gedit test.c 打开和书写文本
在Linux下没有明确的后缀规定
- C程序编译
gcc test.c -o test 可执行文件化
gcc test.c 编译C文件,默认生成a.out可执行文件
gcc -E test.c -o test.i 预处理化
gcc -S test.i -o test.s 汇编化
gcc -c test.s -o test.o 机器化
as -g test.s -o test.o 机器化
objdump -d test.o 解释机器语言->汇编
gcc test.o -o test.out 链接、分配
ld test.o -o test 链接、分配
- GDB调试
1.GDB
gcc -g test.c -o test 调试编译
gdb test /
gdb -q test /
gdb -q
file test 启动调试
shell clear 清屏
help/h +命令 查看命令帮助
2. layout
layout src:显示源代码窗口
layout asm:显示汇编窗口
layout regs:显示源代码和寄存器窗口
layout split:显示源代码和汇编窗口
layout next:显示下一个layout
layout prev:显示上一个layout
Ctrl + L:刷新窗口
Ctrl + x,再按1:单窗口模式,显示一个窗口
Ctrl + x,再按2:双窗口模式,显示两个窗口
Ctrl + x,再按a:回到传统模式,即退出layout,回到执行layout之前的调试窗口。
3.C
list/l:查看C代码(list 5 list 5,10 list func list test.c:5,10 ) reverse-search str/search str
break/b+num if :在C代码第num行设置断点
run/r:重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件)
start:单步执行,运行程序,停在第一C执行语句
continue/c:程序继续运行,直到下个C断点或者结束
next/n:单步C代码调试(逐函数直接执行)
step/s:单步C代码调试(跳入自定义函数内部执行)
finish:结束当前函数,返回到函数调用点
jump:直接跳到C指定行继续执行程序
until:运行程序直到退出循环体;
4.汇编
set disassembly-flavor intel 转换为intel格式的汇编
set disassembly-flavor att 转换为AT&T格式的汇编
disassemble /mr main :显示汇编代码(/m源码和汇编排列,/r看16进制代码)
disassemble add1 add2 :显示add1到2之间的汇编代码
disassemble add1/函数名 ,+[length] 显示指定地址后面length的汇编代码
break *_start + length 汇编起始处length处断点
break *main+偏移 汇编main处length处断点
run
ni/si 单指令执行
disassemble $pc,+length 显示运行指针length的汇编代码
x/ni main/$pc 查看从main/当前运行地址的n行指令
display/ni $pc 查看从main/当前运行地址的n行指令
5.WATCH
info breakpoints:查看当前设置的所有断点
disable breakpoints:禁用断点
enable breakpoints:启用断点
clear/delete breakpoints:删除断点
watch:被设置观察点的变量发生修改时,打印显示
info watch:显示观察点
display:追踪查看具体变量值
undisplay:取消追踪观察变量
whatis :打印数据类型
print/p/x:打印x格式的值及地址
x add:查看内存的值
x /nxw add: 显示n个单元,x进制,w字节每单元
info registers (寄存器) 表示寄存器的值
set variable 变量=值
quit:退出gdb
(gdb)backtrace:查看函数的调用的栈帧和层级关系,简写bt
(gdb)frame:切换函数的栈帧,简写f
(gdb)info:查看函数内部局部变量的数值,简写i
(gdb)run argv[1] argv[2]:调试时命令行传参
- 拓展
程序基本流程:预处理,编译,汇编,链接
为什么(不同系统、不同编译器,不同架构互相影响,同原理不同方式)不能兼容同一个已编译的可执行二进制文件?
格式不同和API不同,还有ABI应用二进制接口
一个可执行文件要被执行的时候,操作系统需要为其分配资源,这些资源包括:内存空间(物理的和虚拟的),进程、线程资源等等,可执行文件在执行之前,操作系统要有一些准备工作,因为不同的操作系统,准备工作是不同的,所以<二进制可执行文件的格式>不完全相同
一个可执行文件所执行的绝大多数操作(比如:文件操作、输入输出、内存申请释放、任务调度等等)都需要与操作系统交互才能完成,而不同的操作系统使用这些操作的方法API完全不同,所以这个障碍更难跨越。
每个操作系统都会为运行在该系统下的应用程序提供应用程序二进制接口ABI,不同操作系统下接口不同
可以看出,从CPU硬件到操作系统到应用程序到用户,是不断多元化、灵活化的过程,同时也导致不同的操作方法
C语言更接近机器语言和汇编,在编译时产生的汇编和机器特性更加明显,而其他高级语言的各种特性会抹淡汇编和机器特性