Cet article ne couvre que quelques conseils de débogage de base pour Visual Studio, mais il en existe d'autres qui sont tout aussi utiles. J'ai compilé quelques conseils de débogage pour le développement natif dans Visual Studio (au moins sous VS 2008). (Si vous travaillez sous code managé, le débogueur aura plus de fonctionnalités, et il existe des articles les présentant dans CodeProject. Voici quelques conseils que j'ai compilés :
Break on Exception
Pseudo-variables). dans Watch Windows | Lancer le débogueur à partir du code
Imprimer dans la fenêtre Sortie
Isoler les fuites de mémoire
Déboguer la version finale 🎜>
Avant que le gestionnaire ne soit appelé, vous pouvez démarrer le débogueur pour interrompre lorsqu'une exception se produit, vous permettant de déboguer le programme immédiatement après que l'exception se produit. La manipulation de la pile d'appels vous permet de trouver la cause première d'une exception.
Vistual Studio vous permet de spécifier le type d'exception ou l'exception spéciale que vous souhaitez interrompre. Sélectionnez le menu Débogage>Exceptions et une boîte de dialogue apparaîtra. Vous pouvez spécifier des exceptions natives (ou gérées) En plus de certaines des exceptions par défaut fournies avec le débogueur, vous pouvez également ajouter vos propres exceptions personnalisées.
Ce qui suit est un exemple de rupture du débogueur lorsqu'une exception std::exception est levée.
La fenêtre Espion ou la boîte de dialogue QuickWatch fournit des variables spécifiques (reconnaissables par le débogueur), qui sont appelées variables factices. Le document contient les éléments suivants :
$tid——ID du thread du thread actuel
$pid——ID du processus$cmdline——Chaîne de ligne de commande pour démarrer le programme $user — ——-Informations sur le compte du programme en cours d'exécution
$registername——-Afficher le contenu du registre registernameDans tous les cas, la pseudo variable sur la dernière erreur est très utile :
$err —— – Afficher le code d'erreur de la dernière erreur
$err, hr—Afficher le message d'erreur de la dernière erreur
Astuce 3 : Vérifiez l'objet tas après dépasser les limites
Parfois, après que le symbole de débogage ait dépassé les limites, vous souhaitez toujours afficher la valeur de l'objet. À ce moment, les variables dans la fenêtre de surveillance sont désactivées et ne peuvent plus être affichées (. ou mis à jour), même si l'objet existe toujours. Si vous connaissez l'adresse de l'objet, vous pouvez continuer à l'observer pleinement. Vous pouvez convertir l'adresse en pointeur de ce type d'objet et la placer dans la fenêtre de surveillance.
Dans l'exemple suivant, après avoir quitté do_foo(), _foo n'est plus accessible. Cependant, après avoir converti son adresse en foo*, vous pouvez continuer à observer cet objet.
Astuce 4 : Vérifiez la valeur du tableau
Si vous travaillez avec un très grand tableau (supposons au moins quelques centaines d'éléments, mais peut-être moins), il est difficile d'étendre le tableau dans la fenêtre de surveillance pour rechercher des éléments dans une plage spécifique, car vous devez continuer à faire défiler le tableau. Si le tableau est alloué sur le tas, vous ne pouvez même pas étendre les éléments du tableau dans la fenêtre de surveillance. . C’est vrai. Il existe donc une solution. Vous pouvez utiliser (array
Si votre tableau est sur le tas, vous pouvez le développer dans la montre. window, Mais pour afficher une plage spécifique de valeurs, l'utilisation est légèrement différente : ((T*) array
Si vous utilisez MFC et utilisez le conteneur 'array', comme CArray, CDWordArray, CStringArray, etc. Vous pouvez bien entendu utiliser la même méthode de filtrage. Au-delà de cela, vous devez examiner le membre m_pData du tableau, qui est le cache réel qui contient les données.
Astuce 5 : évitez de saisir des fonctions inutiles
Plusieurs fois, lors du débogage du code, vous pouvez saisir une fonction que vous souhaitez ignorer, comme un constructeur, une affectation opération ou autre. Celui qui me dérange le plus est le constructeur CString. Ce qui suit est un exemple Lorsque vous êtes prêt à accéder à la fonction take_a_string(), entrez d'abord le constructeur CString.
void take_a_string(CString const &text){}void test_string(){ take_a_string(_T("sample"));}
Heureusement, vous pouvez le dire le débogueur quelles méthodes, classes ou espaces de noms entiers ignorer. La méthode pour procéder a également changé, à l'époque de VS6, elle était généralement spécifiée via le fichier autoexp.dat. Visual Studio 2002 a été modifié pour utiliser les paramètres du registre. Pour ignorer certaines fonctions, vous devez ajouter quelques valeurs dans le registre (détails ci-dessous) :
L'emplacement réel dépend de la version de Vistual Studio que vous utilisez et de la plateforme du système d'exploitation (x86 ou x64, car le registre est uniquement consultable sous Windows 64 bits) Le nom de la valeur est un nombre, représentant la priorité de la règle ; plus le nombre est grand, plus la priorité est élevée ; Les données de valeur sont une valeur REG_SZ d'une expression régulière qui spécifie comment filtrer et exécuter.
Pour éviter de saisir des méthodes CString, j'ai ajouté la règle suivante :
Avec cela, même si vous forcez take_a_string() dans l'exemple ci-dessus, le débogueur ignorera également le constructeur de CString.
Astuce 6 : Lancez le débogueur à partir du code
Vous aurez rarement besoin d'attacher un débogueur à un programme, mais vous ne pouvez pas le faire dans la fenêtre Attacher (peut-être à cause d'interruptions qui arrivent trop vite pour être attrapé), vous ne pouvez pas non plus démarrer le programme dans le débogueur au début. Vous pouvez générer une pause dans votre programme pour donner au débogueur une chance de s'attacher en appelant _degbugbreak() en interne.
void break_for_debugging() { __debugbreak(); }
Il existe en fait d'autres façons de le faire, comme déclencher l'interruption 3, mais cela ne fonctionne que sur les plateformes x86 (ASM n'est plus supporté en C 64 bits). Il existe également la fonction DebugBreak(), mais son utilisation n'est pas très simple, il est donc recommandé d'utiliser ici la méthode interne.
__asm int 3;
Le programme cessera de s'exécuter lorsqu'il exécutera une méthode interne. À ce stade, vous avez la possibilité d'attacher un débogueur au processus.
Astuce 7 : Imprimez dans la fenêtre de sortie
Vous pouvez le faire ceci en appelant DebugOutputString Afficher un texte spécifique dans la fenêtre de sortie du débogueur. Si aucun débogueur n’est connecté, cette fonction ne fait rien.
技巧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)就可以识别内存泄漏的起因。
技巧9:调试发行版
调试和发布是两个不同的目的。调试配置是用于开发的,而发布配置,顾名思义,是用来作为程序的最终版本,因为它必须严格遵循发布的质量要求,该配置包含优化部分和调试版本的中断调试的设置。而且,有时候,要像调试调试版本一样去调试发行版。要做到这一点,你需要在配置里做一些改变。但是这种情况下,你就不再是在调试发行版,而是调试和发行的混合版
你还应该做一些事儿,以下是必须要做的:
配置C/C++ >General>Debug Information Format 应该为 “Program Database(/Zi)”
配置C/C++ >Optimization>Optimization 应该为”Disabld(/Od)”
配置Linker>Debugging>Generate Debug Info 应该为”Yes/(DEBUG)”
如图所示:
技巧10:远程调试
另一个重要的调试就是远程调试,这是一个更大的话题,多次被提到,这里我只做一下简单的概括:
你需要在远程机器上安装远程调试监控
远程调试监控必须以管理员身份运行,并且用户必须属于管理员组
在你运行监控时,会开启一个新的服务,该服务的名字必须用Visual Studio的Attach to Progress窗口的Qualifier组合框的值。
远程和本地机器上的防火墙必须允许Visual Studio和远程调试监控之间能够通信
想要调试,PDB文件是关键;为了能够让VisualStudio自动加载它们,必须满足以下条件:
1)本地的PDB文件必须可用(在远程机器的相同路径下放置一个对应的模块)。
2) 远程机器上的托管PDB文化必须可用。
结束语
Ivan Shcherbakov那篇文章和我这篇文章提到的调试技巧,在大多数的调试问题中都是必不可少的。
更多分享Visual Studio原生开发的10个调试技巧相关文章请关注PHP中文网!