Heim  >  Artikel  >  Backend-Entwicklung  >  Teilen Sie 10 Debugging-Tipps für die native Entwicklung von Visual Studio

Teilen Sie 10 Debugging-Tipps für die native Entwicklung von Visual Studio

高洛峰
高洛峰Original
2017-02-07 10:56:011541Durchsuche

In diesem Artikel werden nur einige grundlegende Debugging-Tipps für Visual Studio behandelt, es gibt jedoch auch andere, die ebenso nützlich sind. Ich habe einige Debugging-Tipps für die native Entwicklung in Visual Studio (zumindest unter VS 2008) zusammengestellt. (Wenn Sie mit verwaltetem Code arbeiten, verfügt der Debugger über weitere Funktionen, und es gibt Artikel, die diese in CodeProject vorstellen. Hier sind einige Tipps, die ich zusammengestellt habe:

Break on Exception | in Watch Windows |. Starten Sie den Debugger aus dem Code
Drucken Sie im Ausgabefenster
Debuggen Sie die Release-Version | wenn eine Ausnahme auftritt, sodass Sie das Programm sofort nach Auftreten der Ausnahme debuggen können. Durch Bearbeiten des Aufrufstapels können Sie die Grundursache einer Ausnahme ermitteln.

Mit Visual Studio können Sie den Ausnahmetyp oder die spezielle Ausnahme angeben, die Sie unterbrechen möchten. Wählen Sie das Menü „Debuggen“ > „Ausnahmen“. Daraufhin wird ein Dialogfeld angezeigt. Zusätzlich zu einigen der im Debugger enthaltenen Standardausnahmen können Sie auch Ihre eigenen benutzerdefinierten Ausnahmen hinzufügen.




Das Folgende ist ein Beispiel dafür, wie der Debugger abbricht, wenn eine std::Exception-Ausnahme ausgelöst wird.




Tipp 2: Pseudovariablen im Überwachungsfenster

Das Überwachungsfenster oder das QuickWatch-Dialogfeld bietet einige spezifische (vom Debugger erkennbare) Variablen sogenannte Dummy-Variablen. Das Dokument enthält Folgendes:

$tid – Thread-ID des aktuellen Threads 分享Visual Studio原生开发的10个调试技巧$pid – Prozess-ID

$cmdline – Befehlszeilenzeichenfolge zum Starten des Programms

$user — ——-Kontoinformationen des laufenden Programms

$registername——-Anzeige des Inhalts des Registers registername

In jedem Fall ist die Pseudovariable über den letzten Fehler sehr nützlich: 分享Visual Studio原生开发的10个调试技巧

$err —— – Zeigt den Fehlercode des letzten Fehlers an

$err, hr – Zeigt die Fehlermeldung des letzten Fehlers an




Tipp 3: Überprüfen Sie anschließend das Heap-Objekt Überschreitung der Grenzen

Manchmal möchte man den Wert des Objekts immer noch anzeigen, nachdem das Debug-Symbol die Grenzen überschritten hat. Zu diesem Zeitpunkt sind die Variablen im Überwachungsfenster deaktiviert und können nicht mehr angezeigt werden (. oder aktualisiert), obwohl das Objekt noch existiert. Wenn Sie die Adresse des Objekts kennen, können Sie es weiterhin vollständig beobachten. Sie können die Adresse in einen Zeiger dieses Objekttyps umwandeln und in das Überwachungsfenster einfügen.

Im folgenden Beispiel kann nach dem Verlassen von do_foo() nicht mehr auf _foo zugegriffen werden. Nach der Konvertierung seiner Adresse in foo* können Sie dieses Objekt jedoch weiterhin beobachten.


Tipp 4: Überprüfen Sie den Wert des Arrays 分享Visual Studio原生开发的10个调试技巧

Wenn Sie mit einem sehr großen Array arbeiten (nehmen wir mindestens ein paar hundert Elemente an, aber vielleicht weniger), ist es mühsam, das Array im Überwachungsfenster zu erweitern, um Elemente in einem bestimmten Bereich zu finden, da Sie weiter scrollen müssen. Wenn das Array auf dem Heap zugewiesen ist, können Sie nicht einmal die Array-Elemente im Überwachungsfenster erweitern . Richtig. Deshalb gibt es eine Lösung. Sie können (array+ ab76cfca1a1dc7ff1291dcdf873f72ec) verwenden, um einen bestimmten Bereich von 570b78fce6f4d82c6d7725059f1f48f1-Elementen anzuzeigen (wobei das Array natürlich Ihr eigentliches Objekt ist). Wenn Sie das gesamte Array anzeigen möchten, können Sie einfach array,570b78fce6f4d82c6d7725059f1f48f1 verwenden.





Wenn sich Ihr Array auf dem Heap befindet, können Sie es in der Überwachung erweitern Fenster, aber um einen bestimmten Wertebereich anzuzeigen, ist die Verwendung etwas anders: ((T*) Array + 287aa39994cdf92a832ae375240bc34b),5007ef0bd5ac54a598c5b0c21fee54fc (Beachten Sie, dass diese Verwendung auch für mehrdimensionale Arrays auf dem Heap gilt ). In diesem Fall bezieht sich T jedoch auf den Typ des Array-Elements.

分享Visual Studio原生开发的10个调试技巧

Wenn Sie MFC verwenden und den darin enthaltenen „Array“-Container wie CArray, CDWordArray, CStringArray usw. verwenden. Sie können natürlich dieselbe Filtermethode verwenden. Darüber hinaus müssen Sie sich das m_pData-Mitglied des Arrays ansehen, bei dem es sich um den eigentlichen Cache handelt, der die Daten enthält.

分享Visual Studio原生开发的10个调试技巧

Tipp 5: Vermeiden Sie die Eingabe unnötiger Funktionen

Oft geben Sie beim Debuggen von Code möglicherweise eine Funktion ein, die Sie überspringen möchten, z. B. den Konstruktor oder die Zuweisung Operation oder sonstiges. Was mich am meisten stört, ist der CString-Konstruktor. Das Folgende ist ein Beispiel. Wenn Sie bereit sind, die Funktion take_a_string() auszuführen, geben Sie zunächst den CString-Konstruktor ein.

void take_a_string(CString const &text){}void test_string(){ take_a_string(_T("sample"));}

分享Visual Studio原生开发的10个调试技巧

Zum Glück können Sie es sagen dem Debugger, welche Methoden, Klassen oder ganzen Namespaces übersprungen werden sollen. Auch die Methode hierfür hat sich geändert. Zu Zeiten von VS6 wurde sie normalerweise über die Datei autoexp.dat angegeben. Visual Studio 2002 wurde geändert, um Registrierungseinstellungen zu verwenden. Um einige Funktionen zu überspringen, müssen Sie einige Werte in der Registrierung hinzufügen (Details unten):

Der tatsächliche Speicherort hängt von der Version von Vistual Studio ab, die Sie verwenden, und der Betriebssystemplattform (x86 oder x64, da die Registrierung nur unter 64-Bit-Windows durchsucht werden kann) Der Name des Werts ist eine Zahl, die die Priorität der Regel darstellt; je größer die Zahl, desto höher die Priorität. Bei den Wertdaten handelt es sich um einen REG_SZ-Wert eines regulären Ausdrucks, der angibt, wie gefiltert und ausgeführt wird.

Um die Eingabe von CString-Methoden zu vermeiden, habe ich die folgende Regel hinzugefügt:

分享Visual Studio原生开发的10个调试技巧

Damit, auch wenn Sie take_a_string() im obigen Beispiel erzwingen, Der Debugger überspringt auch den Konstruktor von CString.

Tipp 6: Starten Sie den Debugger aus dem Code

Möglicherweise müssen Sie selten einen Debugger an ein Programm anhängen, aber Sie können dies nicht im Fenster „Anhängen“ tun (möglicherweise, weil dies aufgrund von Interrupts zu schnell geschieht). abgefangen werden), können Sie das Programm auch nicht am Anfang im Debugger starten. Sie können eine Unterbrechung in Ihrem Programm erzeugen, um dem Debugger die Möglichkeit zu geben, eine Verbindung herzustellen, indem Sie intern _degbugbreak() aufrufen.

void break_for_debugging() {
__debugbreak();
}

Es gibt tatsächlich andere Möglichkeiten, dies zu tun, wie zum Beispiel das Auslösen von Interrupt 3, aber das funktioniert nur auf x86-Plattformen (ASM wird in C++ 64-Bit nicht mehr unterstützt). Es gibt auch die Funktion DebugBreak (), deren Verwendung jedoch nicht sehr einfach ist. Daher wird empfohlen, hier die interne Methode zu verwenden.

__asm int 3;

Das Programm stoppt die Ausführung, wenn es eine interne Methode ausführt. Zu diesem Zeitpunkt haben Sie die Möglichkeit, einen Debugger an den Prozess anzuhängen.

分享Visual Studio原生开发的10个调试技巧

分享Visual Studio原生开发的10个调试技巧

分享Visual Studio原生开发的10个调试技巧

Tipp 7: Im Ausgabefenster drucken

Das können Sie tun Rufen Sie dazu DebugOutputString auf und zeigen Sie einen bestimmten Text im Ausgabefenster des Debuggers an. Wenn kein Debugger angeschlossen ist, führt diese Funktion nichts aus.

分享Visual Studio原生开发的10个调试技巧

技巧8:隔离内存泄漏 

内存泄漏是在原生开发中的一个很重要的问题,要检测内存泄漏是一个很严峻的挑战,尤其是在大型项目中。Vistual Studio可以提供检测内存泄漏的报告,还有其他的一些应用程序(免费的或商业的)也可以帮助你检测内存泄漏.有些情况下,在一些内存分配最终会导致泄漏时,可以使用调试器去中断。但是你必须找到可再现的分配编号(尽管没那么容易)。如果能做到这一点,执行程序时调试器才会中断。 

我们来看下面的代码,分配了8个字节,却一直没释放分配的内存。Visual Studio提供了造成内存泄漏的对象的报告,多运行几次,会发现一直是同一个分配编号(341)。 

void leak_some_memory() 
{ 
char* buffer = new char[8]; 
} 
Dumping objects -> 
d:\marius\vc++\debuggingdemos\debuggingdemos.cpp(103) : {341} normal block at 0x00F71F38, 8 bytes long. 
Data: < > CD CD CD CD CD CD CD CD

在一个特定的(可复现的)位置中断的步骤如下: 

确定你有足够的关于内存泄漏的报告模式(参考 使用CRT库检测内存泄漏) 
多次运行程序直到你能在程序运行结束后的内存泄漏报告里找到一个可复现的分配编号,例如上个例子中的(341) 
在程序一开始的地方设置一个断点以便你能够尽早地进行中断。 
当最初的中断发生时,watch窗口的Name栏里会显示:{,,msvcr90d.dll}_crtBreakAlloc,在Value栏里写入你想要查找的位置编号 
继续调试(F5) 
程序执行到指定位置会停止,你可以使用调用栈被指引找到被该位置触发的那段代码。 
遵循这些步骤, 在上个例子中,使用分配的编号(341)就可以识别内存泄漏的起因。 

分享Visual Studio原生开发的10个调试技巧

技巧9:调试发行版 

调试和发布是两个不同的目的。调试配置是用于开发的,而发布配置,顾名思义,是用来作为程序的最终版本,因为它必须严格遵循发布的质量要求,该配置包含优化部分和调试版本的中断调试的设置。而且,有时候,要像调试调试版本一样去调试发行版。要做到这一点,你需要在配置里做一些改变。但是这种情况下,你就不再是在调试发行版,而是调试和发行的混合版

分享Visual Studio原生开发的10个调试技巧

你还应该做一些事儿,以下是必须要做的: 

配置C/C++ >General>Debug Information Format 应该为 “Program Database(/Zi)” 
配置C/C++ >Optimization>Optimization 应该为”Disabld(/Od)” 
配置Linker>Debugging>Generate Debug Info 应该为”Yes/(DEBUG)” 
如图所示: 

分享Visual Studio原生开发的10个调试技巧

技巧10:远程调试 

另一个重要的调试就是远程调试,这是一个更大的话题,多次被提到,这里我只做一下简单的概括: 

你需要在远程机器上安装远程调试监控 
远程调试监控必须以管理员身份运行,并且用户必须属于管理员组 
在你运行监控时,会开启一个新的服务,该服务的名字必须用Visual Studio的Attach to Progress窗口的Qualifier组合框的值。 

分享Visual Studio原生开发的10个调试技巧

分享Visual Studio原生开发的10个调试技巧

远程和本地机器上的防火墙必须允许Visual Studio和远程调试监控之间能够通信

想要调试,PDB文件是关键;为了能够让VisualStudio自动加载它们,必须满足以下条件:

1)本地的PDB文件必须可用(在远程机器的相同路径下放置一个对应的模块)。

 2) 远程机器上的托管PDB文化必须可用。

结束语 

Ivan Shcherbakov那篇文章和我这篇文章提到的调试技巧,在大多数的调试问题中都是必不可少的。

更多分享Visual Studio原生开发的10个调试技巧相关文章请关注PHP中文网!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn