調試(Debug)和發布(Release)

2021-02-06 編程學習基地
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 足足少了2696B,少掉的那部分是什麼呢,如果你了解過 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)

你幾乎什麼都看不到,想破解這個程序難上加難。

相關焦點

  • Go 的 Debug 工具 delve 介紹
    Usage: dlv [command]Available Commands: attach 可以用來對一個正在運行的進行進行調試. connect 連接到headless調試器. core 用來調試core文件.
  • Golang的Debug工具delve介紹
    Usage: dlv [command]Available Commands: attach 可以用來對一個正在運行的進行進行調試. connect 連接到headless調試器. core 用來調試core文件.
  • 關於Flutter打包,你需要知道的基礎配置和包體積優化策略?
    一、背景在本地開發中,使用flutter run命令還是 Android studio 運行或者調試,flutter 構建的是 debug 版本,也就是本地調試右上角出現 debug 標誌。當本地調試 OK 後,準備 release 版本,比如發布到應用商城,或者交付用戶使用。二、前期檢查工作1、檢查AndroidManifest配置查看<app root>/android/app/src/main/中的AndroidManifest.xml文件,並驗證這些屬性是否正確,特別是:•application 屬性,這是應用的名稱。
  • 淺析常見Debug調試器的安全隱患
    1、java JDWP RCEJDWP(Java DEbugger Wire Protocol):即Java調試線協議,是一個為Java調試而設計的通訊交互協議,它定義了調試器和被調試程序之間傳遞的信息的格式。網上已有非常多的JDWP利用分析文章,這裡主要介紹復現過程和指紋識別以及一些小細節。
  • Flutter打包發布
    Android打包和發布 1.1. 填寫應用配置1.1.1. 基本信息在之前講解應用程式的配置信息時,我們已經介紹過,這裡不再過多介紹1.1.2. 版本信息Flutter的版本信息在哪裡填寫呢?           // Signing with the debug keys for now,           // so `flutter run --release` works.
  • 10分鐘學會Bash調試
    " 表示行號,修改 PS4 之後,輸出的調試信息就會包括 腳本名字以及行號我們執行腳本,看下結果[root@VM-0-2-centos shell_debug]# bash -x ta.sh + PS4='+${BASH_SOURCE}:${LINENO} '+ta.sh
  • Python 必備 debug 神器:pdb
    目錄叨逼叨首先,介紹一下 pdb 調試,pdb 是 python 的一個內置模塊,用於命令行來調試 Python 代碼。
  • Python調試工具之pdb
    查看變量值和變量類型是否符合我們預期是DEBUG過程中一項非常重要的工作或目的,很多剛接觸程式語言的人員習慣於採用print輸出中間變量值或者變量類型,1def test():2    x, y = 1, 23    z = x + y4    print(z)567if __name__ == '__main__':
  • TensorFlow 調試程序(一)
    tfdbg 是 TensorFlow 的專用調試程序。藉助該調試程序,您可以在訓練和推理期間查看運行中 TensorFlow 圖的內部結構和狀態,由於 TensorFlow 的計算圖模式,使用通用調試程序(如 Python 的 pdb)很難完成調試。本指南重點介紹 tfdbg 的命令行界面 (CLI)。
  • 深入LUA腳本語言,讓你徹底明白調試原理
    先看一下庫中提供的幾個重要的函數:debug.gethookdebug.sethookdebug.getinfodebug.getlocaldebug.setlocaldebug.setupvaluedebug.tracebackdebug.getregistry
  • Linux 系統動態追蹤(高級調試)技術
    perf_eventperf_event 隨內核的主版本進行發布, 一直是 linux 用戶的主要追蹤工具, 通常由 perf 命令提供服務. 可以支持對 tracepoint, kprobes 和 uprobes 機制的處理, 另外 perf 也是可以對 cpu 性能進行計數的強大工具之一.
  • 使用 GDB + Qemu 調試 Linux 內核
    概述在某些情況下,我們需要對於內核中的流程進行分析,雖然通過 BPF 的技術可以對於函數傳入的參數和返回結果進行展示,但是在流程的調試上還是不如直接 GDB 單步調試來的直接。本文採用的編譯方式如下,在一臺 16 核 CentOS 7.7 的機器上進行內核源碼相關的編譯(主要是考慮編譯效率),調試則是基於 VirtualBox 的 Ubuntu 20.04 系統中,採用 Qemu + GDB 進行單步調試,網上查看了很多文章,在最終進行單步跟蹤的時候,始終不能夠在斷點處停止,進行過多次嘗試和查詢文檔,最終發現需要在內核啟動參數上添加 nokaslr ,本文是對整個搭建過程的總結
  • 一文匯總Linux 系統動態追蹤(高級調試)技術
    , 可以在內核態和用戶態進行深入的分析, 方便開發者或系統管理者便捷快速的定位和處理問題.不過 systemtap 提供了很成熟的調試符號及複雜的探針處理程序, 支持對 tracepoint, kprobes 和 uprobes 的處理, 同時也可以進行內核編程, 以及性能相關的統計分析.
  • 使用 VMware + win10 + VirtualKD + windbg 從零搭建雙機內核調試環境
    順利安裝完系統過後,我們就可以開始進行雙機內核調試了。如果我們希望通過虛擬串口的形式連接,我們在系統設置前,一定要注意:VMware中的印表機會佔用默認的串口 1。如果不移除印表機,我們新建的串口會是串口 2(這樣,我們在被調試系統中設置的時候,需要設定debugport的值為2)。當然,我們可以移除印表機,然後新建串口,這樣新建的串口就是默認的串口 1了。
  • Android Studio五分鐘帶你從菜鳥到高級調試
    自己封裝的網絡框架和網絡請求 。其中令我最頭疼的就是網絡請求的發包和回包以及回包數據的處理。在這個熟悉代碼的過程中最主要的就是調試。以前從沒用過Android Studio 的調試。下面就來簡單介紹一下Android Studio的調試。
  • Android逆向之旅---動態方式破解apk前奏篇(Eclipse動態調試smail源碼)
    2、修改AndroidManifest.xml中的debug屬性和在入口代碼中添加waitDebug上面我們反編譯成功了,下面我們為了後續的調試工作,所以還是需要做兩件事:222》JDWP協議(用於傳輸調試信息的,比如調試的行號,當前的局部變量的信息等),這個就可以說明,為什麼我們在一開始的時候,反編譯成java文件,因為為了Eclipse導入能夠識別的Java文件,然後為什麼能夠調試呢?因為smali文件中有代碼的行號和局部變量等信息,所以可以進行調試的。
  • 內核調試神器SystemTap — 簡介與使用(一)
    安裝依賴包gcc:C語言編譯器elfutils:提供分析調試信息的庫函數linux-headers-generic:編譯內核模塊所需的內核頭文件以及模塊配置信息3.安裝內核調試信息(kernel-debuginfo)kernel-debuginfo提供了調試內核所需的符號表,如果沒有安裝的話SystemTap的威力就會大打折扣,只能提供kprobes系列的功能。
  • 以太坊模擬器Ganache v7重磅發布!
    以太坊模擬器Ganache v7
  • Python使用pdb更優雅的調試代碼
    如果沒有IDE或者命令行寫代碼時又該怎樣快速調試?這時如果使用pdb進行調試將會異常方便。Pdb就是Python debugger ,是python自帶的調試器。通過 pdb 我們可以交互式的查看運行過程中變量的值、設置斷點、逐行執行代碼、查看代碼的調用棧等等。並且如果環境沒有 GUI 的話,那麼 pdb 能夠助你更快速的調試代碼。
  • 我在MTK平臺下調試音頻ALSA
    #前言前言我就隨便寫了,因為是項目的需要,我需要在我們的MTK8167S平臺上面調試音頻。包括錄音和播放。#硬體原理圖因為是我們公司的項目,我就不能把完整的原理圖給出來。因為兩個MIC不涉及機密,跟MTK的公版是一樣的。可以給出來大家看看。