Debug是啥?
「DEBUG」是计算机「排除故障」的意思。马克2号(Harvard Mark II)编制程序的格蕾丝·霍珀(Grace Hopper)是一位美国海军准将及计算机科学家,同时也是世界最早的一批程序设计师之一。有一天,她在调试设备时出现故障,拆开继电器后,发现有只飞蛾被夹扁在触点中间,从而“卡”住了机器的运行。于是,霍珀诙谐地把程序故障统称为“臭虫(BUG)”,把排除程序故障叫DEBUG,而这奇怪的“称呼”,竟成为后来计算机领域的专业行话。
Release
,英文翻译就是'发布'
的意思
Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。
「Release」 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。
「对于初学者最疑惑的问题就是:我刚运行没问题,发给我同学在怎么就跑步起来呢,恼火、、」
这个问题就是你给别人 Debug 版本,而 Debug 版本带了一些调试信息,这可能会调用一些 dll 文件动态加载,而直接发送到其他主机结果可想而知,运行报错...
解决办法就是生成 Release 版本。当然如果你想让程序拥有一个安装流程,你可以看下以前的推送。
Windows 下 debug 和 release 怎么区分,相信用过VS的你已经知道了,那 Linux 下有 debug 和 release 的区别吗?
答案是有的,那我们来实验证明一下:
测试代码:
#include<stdio.h>
int fun(const char *src,const char *dest)
{
int ret = strcmp(src,dest);
return ret;
}
int main()
{
char password[20] = "123456";
int ret = fun("123456",password);
if(ret==0)
printf("logo in\n");
else
printf("logo fail\n");
return 0;
}
代码很简单,一个登陆判断函数 fun() 和主函数 main()
我们用 -g
选项编译一下
gcc -g -o test-debug test.c
去掉 -g
选项再编译一下
gcc -o test-debug-temp test.c
我们来比较一下他们的大小
deroy@ubuntu:~/deroy$ ls -l
total 28
-rw-r--r-- 1 deroy deroy 264 Jan 25 05:57 test.c
-rwxr-xr-x 1 deroy deroy 11120 Jan 25 06:00 test-debug
-rwxr-xr-x 1 deroy deroy 8424 Jan 25 06:01 test-debug-temp
不加 -g
足足少了2696
B,少掉的那部分是什么呢,如果你了解过 gdb 那你就知道少掉的那部分是源码调试信息。
你以为不就 -g 选项就是 release 版本了吗?天真
我们用readelf -s
命令来查看一下不加 -g 选项能看到什么,这个命令是用来查看二进制信息的,也可以查看符号表。
deroy@ubuntu:~/deroy$ readelf -s test-debug-temp
......
50: 00000000000006fa 43 FUNC GLOBAL DEFAULT 14 fun
......
61: 0000000000000725 134 FUNC GLOBAL DEFAULT 14 main
......
65: 0000000000000580 0 FUNC GLOBAL DEFAULT 11 _init
「我的fun函数怎么暴露了、」
我们将程序里面的「符号表」去掉,来看下「release」版本
objcopy --strip-debug test-debug-temp test-release
啥也别说,先比「大小」
deroy@ubuntu:~/deroy$ ls -l
total 40
-rw-r--r-- 1 deroy deroy 264 Jan 25 05:57 test.c
-rwxr-xr-x 1 deroy deroy 11120 Jan 25 06:00 test-debug
-rwxr-xr-x 1 deroy deroy 8424 Jan 25 06:01 test-debug-temp
-rwxr-xr-x 1 deroy deroy 8312 Jan 25 06:10 test-release
就只少了112
B,感觉readelf -s
还是会暴露我们的函数名称和地址
deroy@ubuntu:~/deroy$ readelf -s test-debug-temp
......
50: 00000000000006fa 43 FUNC GLOBAL DEFAULT 14 fun
......
61: 0000000000000725 134 FUNC GLOBAL DEFAULT 14 main
......
65: 0000000000000580 0 FUNC GLOBAL DEFAULT 11 _init
果不其然,没关系,我们还有终级绝招
再次strip
深度清除符号表
strip test-release
什么都别说先看大小
deroy@ubuntu:~/deroy$ ls -l
total 36
-rw-r--r-- 1 deroy deroy 264 Jan 25 05:57 test.c
-rwxr-xr-x 1 deroy deroy 11120 Jan 25 06:00 test-debug
-rwxr-xr-x 1 deroy deroy 8424 Jan 25 06:01 test-debug-temp
-rwxr-xr-x 1 deroy deroy 6120 Jan 25 06:12 test-release
比 debug 版本足足少了 5k,再次查看符号表
deroy@ubuntu:~/deroy$ readelf -s test-release
Symbol table '.dynsym' contains 9 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5 (2)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __stack_chk_fail@GLIBC_2.4 (3)
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strcmp@GLIBC_2.2.5 (2)
6: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
7: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
8: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.2.5 (2)
你几乎什么都看不到,想破解这个程序难上加难。