Debug code using visual maps

Introduction

Debuggers aren’t much use when you first begin working on a bug, because before you can use one you need to know where to set your breakpoints.

When debugging with AppMap, you don’t need to know where the bug is. You can start from a high-level function, such as an HTTP server request, or you can go “bottom-up” and start with a low-level function or SQL query. Either way, an AppMap provides interactive maps of all the factors that might be contributing to the bug, and helps you figure out where things are going wrong. You can quickly navigate around the source code, knowing which code is relevant to the bug, and which code isn’t. And you can see parameter values, HTTP server and client requests, and complete SQL queries. In many cases, you won’t even need the debugger; just AppMap and your rubber ducky.

Typical debugger screenshot A breakpoint will tell me exactly what’s going on in the code. But how am I supposed to know where to put it?

How it works

The AppMap Trace view provides a detailed, interactive picture of code behavior. So, the first step in debugging with AppMap is to record a test case or example scenario that reproduces the bug. Once you have the AppMap you need, you can use the Trace view to examine a wealth of information that will usually indicate where the bug is happening in the code base. Parameters, return values, status codes, SQL, exceptions, URLs, route names, function labels, and library functions are all available. Sometimes, a bottom-up approach is more productive than top-down. For example, you may know that the bug is related to SQL, but you don’t know where the SQL is coming from. In the AppMap dependency view, you can click on the Database to see all the SQL queries. You can click on a query and then reveal that query in the Trace view, which will show you the complete code execution context around that query. Even if the query was generated by complicated code or an object-relational mapping library, you’ll see the raw SQL exactly as it was sent to the database.

As you explore code behavior using these methods, you may be able to solve the bug using the AppMap alone. If not, you’ll have a great idea where to set your breakpoints to continue your investigation.

Step-by-step

Reproduce the bug
Open the AppMap
Use the AppMap diagrams to inspect the code behavior
Record and publish your solution

Reproduce the bug

The best way to get started is with a test case which reproduces the bug. If a test case is not available, you have a couple of alternatives:

  • Obtain an AppMap from the issue in which the bug is reported
  • Obtain an AppMap by an alternative recording method.

Failing test case screenshot
A failing test case is the best way to start fixing a bug

Open the AppMap

The AppMap extension for your code editor brings full-featured interactive diagrams for viewing, searching and exploring AppMaps right into the development environment.

AppMap command in Visual Studio Code
The AppMap extension provides a smooth pre-debugging user experience

Use the AppMap diagrams to inspect the code behavior

Like a debugger, an AppMap contains parameter names and values. Unlike a debugger, you can explore the code execution in any order you like. You can jump forwards, backwards, up, down. All the data is pre-recorded, so you can view any event you like, in any order.

The visual AppMap is helpful for debugging in two ways. First, when you look at the Component diagram, you’re only seeing the classes and packages that are actually involved in the buggy code path. So, you can step through the control flow starting from the highest level and drilling down into the details, and you can jump into source code at any point. The Component diagram is like an automatic table of contents of all the code that matters for the bug.

Explore trace view screenshot Code flow, variable values, SQL, and source code, all integrated together

Second, when you spot something in the code flow that looks useful or suspicious, you can jump over to the Events view. Here you can see all the details of the functional call tree, and you can see details such as:

  • Parameter values
  • HTTP server and client requests
  • Request status codes and headers
  • SQL queries

Code flow details screenshot
If there’s a problem with this flow, you definitely need to get to the bottom of it…

It’s often possible to spot the bug from this information alone. But if you can’t quite figure out where the bug is happening, the source code which is linked from the diagrams provides ideal places to set breakpoints.

[optional] Run the debugger

Now you’ve got a test case that reproduces the bug, and you’ve got a good idea of where to set breakpoints in order to pinpoint the problem. Run the test case again, and see if your hypothesis checks out.

Record and publish your solution

This video shows how to use AppMaps for documentation of code issues and fixes.


Was this page helpful? thumb_up Yes thumb_down No
Thank you for your feedback!