1. 程式人生 > >Visual Studio之RelWithDebInfo模式,“被忽視”的編譯模式

Visual Studio之RelWithDebInfo模式,“被忽視”的編譯模式

本文由Markdown語法編輯器編輯完成。

1. 背景:

在Visual Studio的編譯模式選項中,一般有四個模式:Debug, Release, RelWithDebInfo, MinSizeRel。

大家一般對前兩個模式比較多。Debug版本是除錯版本,對程式碼不做任何優化,可以debug專案中的任意檔案;Release版本是發行版本,顧名思義就是當程式開發完成後,程式的一個釋出版,它對程式碼做了優化,因此速度會非常快,但是遺憾的是,release版本無法跟蹤程式碼。

根據以上描述,debug和release版本各有自己的優勢和缺陷。
debug版本為了追求更全面的除錯資訊而放棄了速度;


release版本為了追求效能優化而拋棄了除錯資訊。

如果使用者既需要除錯程式碼,又無奈於debug版本的速度,那麼你便可以開始考慮RelWithDebInfo這個版本了。

顧名思義,從這個模式的名稱來看,它是一種含有除錯資訊的Release版本。那麼它相當於是結合了Debug和Release版本的優點的一個版本。

The main differences being that in Debug mode, the executable produced isn’t optimized (as this could make debugging harder) and the debug symbols are included.

The difference between Debug and RelWithDebInfo is mentioned here:

RelWithDebInfo is quite similar to Release mode. It produces fully optimized code, but also builds the program database, and inserts dubug line information to give a debugger a good chance at guessing where in the code you are at any time.


RelWithDebInfo模式是非常近似於Release模式的。它生成出幾乎完全優化的程式碼,而且也建立程式的資料庫,插入一些除錯資訊以使除錯人員能夠有機會去跟蹤你任意時刻正處於哪段程式碼中。

本文將講解如何利用這種模式,在即保證速度快的情況下,同時還可以新增斷點並進行程式碼除錯。你一旦瞭解了這個模式,我想以後完全可以拋棄掉Debug模式了。至少對於我而言,自從我學會了如何正確地使用RelWithDebInfo模式後,我就再也不想啟動Debug模式了。

2. RelWithDebInfo模式:

首先Visual Studio在第一次安裝並配置為Visual Studio C++開發環境後,預設就會有四種編譯模式。分別為(按首字母排序):Debug, MinSizeRel, Release, RelWithDebInfo
這裡寫圖片描述

這裡注意:如果不是用VS的自建工程方式建立工程,而是用如CMake這樣的工具生成工具時,有時候預設是不會生成MinSizeRel和RelWithDebInfo模式的。
比如用CMake編譯VTK-6.3的原始碼時,在勾選了Grouped和Advanced的checkbox後,在下面的選項欄目中,在CMake那欄的CMAKE_CONFIGURATION_TYPES後,就會顯示需要生成的編譯模式,如果沒有RelWithDebInfo這項,使用者可以手動輸入這個選項即可。
這裡寫圖片描述

最常用的無疑是Debug和Release模式了,而在開發過程中,更是幾乎要用Debug模式來除錯程式碼和查詢bug。但是,Debug模式由於所有工程全部附帶了編譯資訊,不做任何優化,使得在實際除錯時,會非常影響除錯速度。如果僅僅是除錯一兩次還無所謂,但是對於一天要啟動程式幾十次甚至幾百次的頻繁除錯,浪費的時間就非常可觀了。

這裡就以編譯VTK-6.3的原始碼和例子作為示例,介紹如何使用RelWithDebInfo模式來除錯程式碼。

2.1 在CMake中選擇編譯Examples。

將編譯模式由原來的Debug模式切換到RelWithDebInfo模式,同時勾選BUILD欄目下的BUILD_EXAMPLES選項,編譯VTK-6.3自帶的例子。設定如下圖所示。
這裡寫圖片描述

待VTKExamples.sln專案生成以後,用VS開發這個工程檔案,然後開始編譯,直至專案中的所有例子工程都編譯完成。
這裡寫圖片描述

2.2 以例子工程中的Medical4為例進行除錯。

在該工程名處點選右鍵,在彈出的選項中,選擇Set as StartUp Project,將該工程設為啟動工程,如下圖所示。這樣在執行時,便會進入這個工程的exe中了。
這裡寫圖片描述

2.3 在Medical4.cxx中設定斷點,準備除錯

開啟Medical4.cxx原始碼,在第45行處增加一個斷點。
這裡寫圖片描述

2.4 設定工程的優化選項,由預設的Maximize Speed(/O2)修改為Disabled(/Od)

這一步是最關鍵的。因為RelWithDebInfo模式預設是和Release模式一樣,對工程進行最大性優化以提高速度。而因為我們要單獨除錯某一個工程,因此需要禁用它的優先,所以切換到Disabled模式,即不進行優化。
這裡寫圖片描述

切換完成後,Optimization項修改為Disabled,如圖所示。
這裡寫圖片描述

2.5 重新編譯要除錯的工程

由於RelWithDebInfo模式下,所有的專案都以最優化方式編譯,因此這些專案都是沒有除錯資訊的。當把需要除錯的工程設定為Disabled模式後,需要重新單獨編譯一下這個工程,才可以生成這個工程的編譯資訊。
這裡寫圖片描述

2.6 以非除錯模式啟動程式(Start without Debugging)。

這一步也是非常關鍵的。因為我們不是要對整個工程專案進行除錯,而只是對特定的某個工程進行除錯,因此啟動執行時為了保證速度,應該選擇Start without Debugging這個選項。快捷鍵為Ctrl+F5。
這裡寫圖片描述

2.7 設定抓取特定程序,進入斷點除錯。

點選選單欄TOOLS選項,選擇Attach to Process選項,準備抓取程序。
這裡寫圖片描述

點選Attach to Process選項後,在彈出的視窗中會顯示目前電腦中正在執行的程序,在Available Processes中。在這些正在執行的程序中選擇Medical4.exe,再點選右下角的Attach按鈕,則完成了抓取程序的設定。
這裡寫圖片描述

2.8 斷點除錯

這裡不太方便演示這一點。
原因在於,Medical4.exe是一個單獨的應用程式。如果沒有啟動這個exe的時候,在Available Processes中是沒有Medical4.exe這個程序的。但是如果啟動了這個exe後,之前標註斷點的語句已經執行完成。此時如果再Attach程序的話,已經無法進入斷點了。

但是,如果是在一個比較大的專案中,工程之間存在相互呼叫的關係。那麼在啟動整個專案的exe後,在程序中便可以捕捉到。然後在後面需要除錯的原始碼中增加斷點,則當流程中執行到需要呼叫那個模組的時候,便會進入斷點了。這樣便實現了以Release的速度執行程式,而以Debug的方式來除錯需要關注的程式碼段。

備註:

其實2.4的步驟,即將Optimization由Maximize Speed切換為Disabled不是必須的,也可以實現在RelWithDebInfo模式中除錯程式碼。但是,這時,在除錯的過程中,會發現進入斷點後,程式執行比較奇怪。例如,如果有if…else分支時,有時候既會進入if分支,也會進入else分支,而且如果想檢視某個程式碼段的變數值,會發現變數值無法顯示或者顯示結果異常。

因此,如果想得到最準確的除錯資訊,還是需要首先將要debug的那個工程,禁用最優化速度才可以。

完!

相關推薦

Visual StudioRelWithDebInfo模式忽視”的編譯模式

本文由Markdown語法編輯器編輯完成。 1. 背景: 在Visual Studio的編譯模式選項中,一般有四個模式:Debug, Release, RelWithDebInfo, MinSizeRel。 大家一般對前兩個模式比較多。Debug版本是

10.【轉】Visual Studio Code 必備外掛主題及語法提示

原文地址:http://www.css88.com/archives/8064 小編推薦:掘金是一個面向程式設計師的高質量技術社群,從 一線大廠經驗分享到前端開發最佳實踐,無論是入門還是進階,來掘金你不會錯過前端開發的任何一個技術乾貨。 Visual Studio Code 是由微軟開發的一款免

關於Visual Studio除錯C/C++JSPHPJAVAPython等語言的方法

我在開始接觸vs code後,確實對它的高顏值和小巧靈活而著迷,但是有一個非常現實的問題,相對於vs來說,vscode是一個程式碼編輯器,而不是一個IDLE,在程式碼編譯執行上存在著極大的問題,尤其是開始編譯C語言的時候,一直不行啊(瘋掉)。在百度的過程中,各種修改launch.json我都試過後,實在是失去

Visual Studio Code 漢化Visual Studio Code 配置

Visual Studio Code 漢化,Visual Studio Code 配置 Visual Studio Code新增vue.js外掛,vue.js程式碼提示外掛     ================================ ©Copyright 

大資料Spark(八)--- Spark閉包處理Spark的應用的部署模式Spark叢集的模式啟動Spark On Yarn模式Spark的高可用配置

一、Spark閉包處理 ------------------------------------------------------------ RDD,resilient distributed dataset,彈性(容錯)分散式資料集。 分割槽列表,fun

window下go語言環境搭建+Visual Studio Code整合go簡潔快速易懂!

IDE用的微軟的Visual Studio Code 開始搭建環境 .2. Go語言環境測試 文字編輯器中編寫hello.go package main import "fmt" func main() { fmt.Println("he

微軟推出Visual Studio Kubernetes工具包.NET網頁應用也能整合Kubernetes_Kubernetes中文社群

除了公有云基礎架構環境要支援Kubernetes,微軟現在也針對開發者需要的開發環境,加強支援Kubernetes。在近日,微軟Visual Studio團隊就表示,為了讓開發者更方便在Kubernetes環境中,構建容器應用,推出了Visual Studio Kubernetes工具包。 跟

Android Studiomaven CentralJCenter

Android studio 是從哪裡得到庫的? Android Studio是從build.gradle裡面定義的Maven 倉庫伺服器上下載library的。Apache Maven是Apache開發的一個工具,提供了用於貢獻library的檔案伺服器。總

visual studio 2010 專案檔案""已重新命名或已不在解決方案中"---解決辦法 .

多個專案的原始碼在一個原始碼中,其中,有一個原始碼廢棄不可用了。刪除後,再次生成解決方案時出現了問題,提示如下圖: 解決方法是:         1、找到主專案,右鍵該專案,點選屬性頁。     2、在本屬性頁中,找到不可用的專案,點選,然後下方點選移除即可。         

Android Studiomaven CentralJCenter(build.gradle、gradle-wrapper.properties、gradle.properties)

Android studio 是從哪裡得到庫的? Android Studio是從build.gradle裡面定義的Maven 倉庫伺服器上下載library的。Apache Maven是Apache開發的一個工具,提供了用於貢獻library的檔案伺服器。總的來說,只

Visual Studio 2013 配置Boost庫。 如何編譯和選擇遇到無法開啟檔案“libboost_thread-vc120-mt-gd-1_58.lib的解決辦法

來源:http://www.th7.cn/Program/cp/201508/522064.shtml 1.到官網下載最新的boost,www.boost.org 這裡我下載的1-58版本 2.解壓 3.從開始選單開啟VS的Visual Studio Tools,選

Visual StudioOpenCL庫環境永久配置

VisualStudio之OpenCL庫環境永久配置 ==============================================================主要內容:配置OpenCL庫環境 ================================

Visual Studio 2015 key 許可證下載地址

ont nal cdh pri unit content sdn 中文版 ng- Visual Studio 2015正式版離線iso及在線下載,附專業版和企業版可用key! Visual Studio Community 2015簡體中文版(社區版,針對個人

設計模式5(命令模式叠代器模式

對象的訪問 叠代器模式 元素 div 使用 ble col top 執行 命令模式 本質是封閉請求,其關鍵是把請求封閉成對象,也就是命令對象,並定義了統一的執行操作的接口,這個命令可以存儲、轉發、記錄、處理、撤消等。整個命令模式都是圍繞這個對象進行。 命令

關於js的設計模式(簡單工廠模式構造函數模式原型模式混合模式動態模式

nod nodejs 重新 作用域 this 一次 無法 typeof 訪問 <1>工廠模式 簡單來說就是封裝後的代碼,簡單的工廠模式是很好理解的,關於它的作用,就是利用面向對象的方法,把一些對象封裝,使一些占用空間多的,重復的代碼封裝起來。實現方法非常簡單,也

C/S模式發布/訂閱模式和PUSH/PULL模式(上)

沒有 入庫 即使 分時 流程 https 分享圖片 內容 怎麽 CS模式(客戶端/服務器模式) 最場景的信息傳遞模式,也稱為Request/Response模式,或者調用模式。http/https協議即此模式。因為最常用所以大家一般都比較熟悉,這裏不重點講了,大家請看圖下圖

Android 判斷是開發debug模式還是釋出release模式

publicclass LogUtils {      publicstaticboolean APP_DBG = false; // 是否是debug模式    publicstaticvoid init(Context context){          APP_DBG

模版方法模式迭代器模式組合模式狀態模式代理模式

1.模版方法模式:在一個方法中定義一個演算法的骨架,而將一些步驟延遲到子類中,模版方法使得子類可以在不改變演算法結構的情況下,重新定義演算法中的某些步驟,還可以提供hook()讓子類決定是否執行某些步驟。比如sort中的Comparable介面。 2.迭代器模式就是集合的迭代器 3.組合模式

Android 工廠模式三種工廠模式的理解

工廠模式是一種建立者模式,在任何生成複雜物件的地方都可以使用工廠模式。理論來說在任何使用A a = new A()的方式都可以使用工廠模式,雖然使用工廠模式可能需要多做一些工作,但是在後續的開發和維護都帶來了方便。 如果我們需要在構建物件的時候,需要做很多的處

使用Visual Studio Code搭建Windows下的Postgresql編譯、除錯環境

一、Visual Stdio Code作為微軟近期推出的跨平臺程式碼編寫工具,今年已經推出C/C++語言外掛,可以進行C/C++語言的編寫,並可以進行直接的編譯和除錯。VSC目前雖然還存在不少問題,比如開啟文件的效率偏低,其整合的外掛功能相對於Windows平臺下的Visu