Tag: debugger

Entries for tag "debugger", ordered from most recent. Entry count: 4.

Warning! Some information on this page is older than 6 years now. I keep it for reference, but it probably doesn't reflect my current knowledge and beliefs.

Pages: 1

# Two most obscure bugs in my life

Wed
14
Nov 2018

Fixing bugs is a significant part of software development, and a very emotional one - from frustration when you have no idea what is happening to euphoria when you find the cause and you know how to fix it. There are many different kinds of bugs and reasons why they are introduced to the code. (Conducting a deep investigation of how each bug happened might be an interesting idea - I will write a separate blog post about it someday...) But the most frustrating ones are probably these that occur only in some specific conditions, like only on one of many supported platforms or only in "Release" and not in "Debug" configuration. Below you will find description of the two most obscure bugs I've found and fixed in my life, for your education and amusement :) Both were in large, multiplatform, C++ codebases.

1. There was this bug reported causing incorrect program behavior, occurring on only one of many platforms where the program was built and used. It was probably Mac, but I can't remember exactly. It was classified as a regression - it used to work before and stopped working, caught by automated tests, after some specific code change. The strange thing was that the culprit submit to the code repository introduced only new comments and nothing else. How can change in a code comment introduce a new bug?!

It turned out that the author of this change wanted to draw a nice "ASCII art" in his comment, so he's put something like this:

// HERE STARTS AN IMPORTANT SECTION
//==================================================================\\
Function1();
Function2();
(...)

Have you noticed anything suspicious?...

A backslash '\' at the end of line in C/C++ means that the logical line is continued to next line. This feature is used mostly when writing complex preprocessor macros. But a code starting from two slashes '//' begins a comment that spans until the end of line. Now the question is: Does the single-line comment span to next line as well? In other words: Is the first function call commented out, or not?

I don't know and I don't really care that much about what would "language lawyers" read from the C++ specification and define as a proper behavior. The real situation was that compilers used on some platforms considered the single-line comment to span to the next line, thus commenting out call to Function1(), while others didn't. That caused the bug to occur on some platforms only.

The solution was obviously to change the comment not to contain backslash at the end of line, even at the expense of aesthetics and symmetry of this little piece of art :)

2. I was assigned a "stack overflow" bug occurring only in "Debug" and not in "Release" configuration of a Visual Studio project. At first, I was pretty sure it would be easy to find. After all, "stack overflow" usually means infinite recursion, right? The stack is the piece of memory where local function variables are allocated, along with return addresses from nested function calls. They tend not to be too big, while the stack is 1 MB by default, so there must be unreasonable call depth involved to hit that error.

It turned out not to be true. After few debugging sessions and reading the code involved, I understood that there was no infinite recursion there. It was a traversal of a tree structure, but the depth of its hierarchy was not large enough to be of a concern. It took me a while to realize that the stack was bloated to the extent that exceeded its capacity by one function. It was a very long function - you know, this kind of function that you can see in corporate environment which defies any good practices, but no one feels responsible to refactor. It must have grown over time with more and more code added gradually until it reached many hundreds of lines. It was just one big switch with lots of code in each case.

void Function(Option op)
{
  switch(op)
  {
  case OPTION_FIRST:
    // Lots of code, local variables, and stuff...
    break;
  case OPTION_SECOND:
    // Lots of code, local variables, and stuff...
    break;
  case OPTION_THIRD:
    // Lots of code, local variables, and stuff...
    break;
  ...
  }
}

What really caused the bug was the number and size of local variables used in this function. Each of the cases involved many variables, some big like fixed-size arrays or objects of some classes, defined by value on the stack. It was enough to call this function recursively just few times to exhaust the stack capacity.

Why "stack overflow" occurred in "Debug" configuration only and not in "Release"? Apparently Visual Studio compiler can lazily allocate or alias local variables used in different cases of a switch instruction, while "Debug" configuration has all the optimizations disabled and so it allocates all these variables with every function call.

The solution was just to refactor this long function with a switch - to place the code from each case in a separate, new function.

What are the most obscure bugs you've met in your coding practice? Let me know in the comments below.

Comments | #debugger #visual studio #c++ Share

# The Importance of Good Debugging Tools

Thu
28
May 2015

Robert L. Glass wrote an interesting article "Frequently Forgotten Fundamental Facts about Software Engineering". While I am aware he is far more experienced than me and he has sources to backup his opinions, I dare to disagree with following paragraph:

T1. Most software tool and technique improvements account for about a 5- to 30-percent increase in productivity and quality. But at one time or another, most of these improvements have been claimed by someone to have "order of magnitude" (factor of 10) benefits. Hype is the plague on the house of software.

I think that having good tools is one of the most important (and sometimes underrated) factors in programmers' efficiency. From comfortable chair, through fast desktop PC, big monitors, fast Internet connection, to good software, including IDE (editor, compiler, debugger etc.) and auxiliary applications (like Total Commander for file management) - they can all make big difference in how developers feel about their job and how fast the work is going.

Of course, "tools" is a broad term. If by choosing good tools we mean changing used programming language or libraries in the middle of the project, then sure it is usually a bad idea. Writing a script to automate some task that can be done manually in just few minutes or even an hour is usually not worth doing as well.

But what is always worth investing time and money in (either buying or developing your own, learning to use them) are tools that help with debugging. As debugging is the hardest and most time consuming part of programming, any improvement in that process can make as big difference as between minutes and weeks - often in the most critical time, close to the deadline.

So in my opinion, being able to interactively debug executing program (or its trace) - to setup a breakpoint and preview current value of variables (as opposed to relying only on some debug text prints, analyzing logs or some command-line tools) is an absolute minimum to be able to call any programming environment reasonable, mature and eligible to write any serious software in it. If you are the one who writes a program and you have to treat that program as a black box while it is running, without a possibility to peek inside, then something is wrong. AFAIK that is the case with some technologies that deploy program to a server or an embedded device.

How is it in graphics programming? John Carmack once tweeted:

gl_FragColor.x = 1.0; is the printf of graphics debugging. Stone knives and bearskins.

While I share his frustration with such primitive methods of debugging, the reality of today's GPU programming is not all that bad as we could only render red pixels to see any debug information. NVIDIA Nsight offers debugging of a GPU, and so does Intel Graphics Performance Analyzers (GPA). Finally, there is a vendor-agnostic debugger for DirectX developed by Microsoft. Originating from Xbox (that is where its name comes from - Performance Investigator for Xbox), PIX used to be available for free as a standalone application. Recently, they have integrated it as part of Visual Studio called Graphics Diagnostics. It was available in commercial versions of Visual Studio only and not in free Express edition (very bad news for all amateur DirectX game developers), but finally they shipped it for free together with the new, fully-functional Visual Studio Community edition.

With these tools, there is no explanation for whining "nothing renders and I don't know why" - just go debug it! :) The future also looks bright. DirectX 12 will offer Debug layer. Vulkan also claims to support debugging tools and layers and LunarG company even started working on such tool - GLAVE.

Comments | #debugger #software engineering Share

# Type Visualization in Visual Studio 2012 Debugger

Tue
23
Apr 2013

When you code in C++ and you have your own library of data types, especially containers, it would be nice to be able to see it in the debugger formatted in some readable way. In Visual C++/Visual Studio, there used to be a special file autoexp.dat designed for this purpose, as described in "Writing custom visualizers for Visual Studio 2005". But it had weird syntax and poor error reporting.

Now in Visual Studio 2012 there is a new way of defining debugger visualizations for native data types, called Native Type Visualization Framework (natvis). All you need to do is to create an XML file with ".natvis" extension following special format and place it in directory: %USERPROFILE%\Documents\Visual Studio 2012\Visualizers. Full documentation of this format is on this single MSDN page: "Creating custom views of native objects in the debugger". See also "Expressions in Native C++" and "Format Specifiers in C++".

For example, if you have a singly linked list:

template<typename T>
class CLinkedList {
   // ...
    struct CNode {
       T Value;
       CNode* Next;
    };
    size_t Count;
    CNode* Head;
};

Default visualization of a 3-element object in the debugger would look like this:

But if you create following natvis file:

<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
   <Type Name="CLinkedList&lt;*&gt;">
       <DisplayString>{{Count = {Count}}}</DisplayString>
       <Expand>
           <Item Name="[Count]">Count</Item>
           <LinkedListItems>
               <Size>Count</Size>
               <HeadPointer>Head</HeadPointer>
               <NextPointer>Next</NextPointer>
               <ValueNode>Value</ValueNode>
           </LinkedListItems>
       </Expand>
   </Type>
</AutoVisualizer>

Next time you start debugging (restarting Visual Studio is not required), same object will be shown as:

Besides extracting single fields from objects, evaluating whole C++ expressions and formatting values into a string for summary of whole object, this framework is able to visualize following data structures:

Comments | #visual studio #debugger #c++ Share

# How to Make Visual Studio Debugger not Step Into STL

Fri
10
Feb 2012

It is annoying when you debug your C++ code in Visual Studio, want to step into your function, but the debugger enters source code of some STL container or string. For example, in the following code you will first enter std::basic_string constructor, then std::vector operator[] and then body of MyFunction.

MyFunction(std::string("abc"), myVector[0]);

It turns out there is a way to disable stepping into certain code, using regular expressions. To do this:

  1. Run Registry Editor (regedit.exe).
  2. Navigate to the key appropriate to your version of Visual Studio or Visual C++. "VCExpress" is for free Visual C++ Express, while "VisualStudio" is for commercial Visual Studio. Number is product version. Additional "Wow6432Node" should be used when working in 64-bit Windows. For example:
    • Visual C++ 2005 Express in 32-bit Windows: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VCExpress\8.0\NativeDE\StepOver
    • Visual Studio 2005 Professional in 32-bit Windows: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\NativeDE\StepOver
    • Visual Studio 2008 Professional in 64-bit Windows: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\9.0\NativeDE\StepOver (for version 2008 it's 9.0 not 8.0, the article linked below is wrong!)
    • Visual Studio 2010 Professional in 64-bit Windows: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\NativeDE\StepOver
  3. Create new String Value with any name and a value containing regular expression to match against identifiers you want to exclude, like "std\:\:.+" for all identifiers from STL namespace (including members of std::string, std::vector and so on). I assume you know the syntax of regular expressions.
  4. In Visual up to 2008, it starts working after you start new debug session (e.g. with F5). In Visual 2010, you have to restart whole IDE.

Here is the full story:

In May 2007 I asked the question on forum.warsztat.gd and written this blog entry (in Polish). Now I've also found this article: How to Not Step Into Functions using the Visual C++ Debugger, Andy Pennell's Blog and this StackOverflow question: Is there a way to automatically avoiding stepping into certain functions in Visual Studio?

From that I've learned that Visual Studio 6.0 used autoexp.dat file, while new versions use Windows registry.

Rules entered in registry can be suffixed with case-insensitive "=NoStepInto" (which is the default) or "=StepInto".

Aside from regular expression syntax you can use additional special codes: \cid (identifier), \funct (function name), \scope (class or namespace, like myns::CClass::), \anything (any string) and \oper (C++ operator).

Double backslashes you can meet on some web pages come from the REG file format, where backslash must be additionally escaped, like "\\:". If you enter regular expression straight into regedit, it should be "\:".

NEW: In Visual Studio 2015, it is completely different. To add such entry:

  1. Open file: c:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Packages\Debugger\Visualizers\default.natstepfilter
  2. To be able to modify it, you must overcome two obstacles: 1. It's in Program Files directory, so you have to do it as administrator. 2. The file is Read-Only, so you need to disable this attribute.
  3. Add following entry to this XML file: <Function><Name>std::.+</Name><Action>NoStepInto</Action></Function>

Comments | #c++ #visual studio #debugger Share

Pages: 1

[Download] [Dropbox] [pub] [Mirror] [Privacy policy]
Copyright © 2004-2025