# How to Use Dear ImGui for Debugging in Games: Built-in Tools and Techniques

> Learn to use Dear ImGui for game debugging with its built-in tools. Inspect UI state at runtime without external dependencies for efficient development.

- Repository: [omar/imgui](https://github.com/ocornut/imgui)
- Tags: how-to-guide
- Published: 2026-07-28

---

**Dear ImGui provides built-in debugging utilities accessible through `ImGuiIO` configuration flags, debug windows, and debugger visualizers that allow runtime inspection of UI state without external dependencies.**

Dear ImGui is an immediate-mode graphical user interface library widely used for creating debug interfaces in game development. When integrating Dear ImGui debugging into your game engine, you gain access to a comprehensive suite of runtime inspection tools that visualize draw calls, track widget hierarchies, and trigger breakpoints directly from the UI. These features require no additional libraries and are implemented entirely within the ImGui source tree, making them ideal for rapid iteration during development.

## Enabling Debug Mode Features in ImGuiIO

Before accessing debug windows, you must configure the `ImGuiIO` structure during initialization. The library exposes several boolean flags that activate specific debugging capabilities.

Set these flags immediately after calling `ImGui::CreateContext()`:

```cpp
ImGuiIO& io = ImGui::GetIO();
io.ConfigDebugIsDebuggerPresent = true;   // Indicates a debugger is attached
io.ConfigDebugShowMetrics = true;         // Enables the Metrics/Debugger window
io.ConfigDebugShowDebugLog = true;        // Enables the Debug Log window
io.ConfigDebugShowIdStackTool = true;     // Enables the ID Stack Tool window

```

These configuration options are declared in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) around lines 2510-2535. The `ConfigDebugIsDebuggerPresent` flag is particularly important because it enables the **Item Picker** functionality to safely trigger breakpoints when a debugger is attached.

## Accessing Built-in Debug Windows

The fastest way to access debugging tools is through `ImGui::ShowDemoWindow()`, which contains a dedicated Debug menu. The implementation in [`imgui_demo.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_demo.cpp) (lines 714-730) provides toggle buttons for all major debug interfaces.

```cpp
static bool show_demo = true;
ImGui::ShowDemoWindow(&show_demo);

```

Alternatively, you can invoke specific debug windows directly using the following functions:

- `ImGui::ShowMetricsWindow()` – Displays draw-list statistics and window hierarchy
- `ImGui::ShowDebugLogWindow()` – Shows internal ImGui logging output
- `ImGui::ShowIDStackToolWindow()` – Visualizes the ID stack for the current widget
- `ImGui::ShowStackToolWindow()` – (Legacy alias) Same as above

### Metrics and Debugger Window

The **Metrics/Debugger** window visualizes per-frame statistics including draw-call count, vertex count, texture bindings, and window hierarchy. This tool updates through the `ImGui::UpdateDebugTools()` function in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), providing real-time feedback on UI performance. Use this window to identify bottlenecks such as excessive `ImDrawList` allocations or unnecessary texture switches that impact your game's frame rate.

### Debug Log Window

The **Debug Log** captures internal ImGui warnings and errors, including layout violations and ID conflicts. Entries are added via the `IMGUI_DEBUG_LOG` macro defined in [`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h). You can filter messages by category and severity, making it invaluable for tracking down subtle layout bugs that only appear at specific resolutions or scaling factors.

### ID Stack Tool

Every ImGui widget generates a unique identifier based on its position in the window hierarchy. The **ID Stack Tool** displays the current stack of IDs, helping you diagnose why `IsItemHovered()` or `IsItemClicked()` returns unexpected values. This is essential when debugging complex nested menus or dynamically generated UI elements where label collisions might occur.

### Item Picker and Debugger Breakpoints

The **Item Picker** adds a small button (🪤) next to widgets in the demo window that triggers `IM_DEBUG_BREAK()` when clicked. This macro expands to platform-specific breakpoints: `__debugbreak()` on MSVC, `__builtin_debugtrap()` on GCC/Clang, or a user-defined handler. The implementation resides in [`imgui_demo.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_demo.cpp) around lines 560-585.

When `ConfigDebugIsDebuggerPresent` is true, clicking the picker immediately pauses execution, allowing you to inspect the ImGui context (`GImGui`) and call stack. This provides one-click debugging without manually setting breakpoints in your IDE.

## Debugger Integration and Visualizers

To improve debugging experience in popular IDEs, Dear ImGui ships with custom visualizer files in the `misc/debuggers/` directory:

- **`misc/debuggers/imgui.natvis`** – Visual Studio native visualizer for `ImVector`, `ImGuiWindow`, and other containers
- **`misc/debuggers/imgui.gdb`** – GDB pretty-printer definitions for ImGui types
- **[`misc/debuggers/imgui_lldb.py`](https://github.com/ocornut/imgui/blob/main/misc/debuggers/imgui_lldb.py)** – LLDB synthetic children and summaries for ImGui structures

Load the appropriate file into your debugger configuration to view ImGui containers as readable arrays rather than raw memory pointers. This makes inspecting the draw list or window stack significantly easier during breakpoint sessions.

## Runtime Assertions and Custom Debugging

ImGui defines assertion macros in [`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h) (lines 315-330) that you can leverage in your own code:

- **`IM_ASSERT(condition)`** – Triggers a breakpoint if the condition fails
- **`IM_DEBUG_BREAK()`** – Unconditionally breaks into the debugger
- **`IMGUI_DEBUG_LOG(format, ...)`** – Writes formatted messages to the debug log

Sprinkle `IM_ASSERT` throughout your rendering code to catch illegal states early, such as calling ImGui functions before `NewFrame()` or modifying draw lists after `Render()`. When an assertion triggers, you can inspect the global context `GImGui` to examine the current window, draw list, and frame state.

## Complete Implementation Example

The following example demonstrates initializing ImGui with full debugging support and rendering the debug windows alongside your game UI:

```cpp
// Initialization
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigDebugIsDebuggerPresent = true;
io.ConfigDebugShowMetrics = true;
io.ConfigDebugShowDebugLog = true;

// Main game loop
while (!glfwWindowShouldClose(window))
{
    glfwPollEvents();
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();

    // Your game UI
    ImGui::Begin("Game HUD");
    ImGui::Text("FPS: %.1f", ImGui::GetIO().Framerate);
    if (ImGui::Button("Trigger Event"))
    {
        // Game logic
    }
    ImGui::End();

    // Debug windows
    static bool show_demo = true;
    static bool show_metrics = true;
    static bool show_debug_log = true;
    
    ImGui::ShowDemoWindow(&show_demo);
    ImGui::ShowMetricsWindow(&show_metrics);
    ImGui::ShowDebugLogWindow(&show_debug_log);

    ImGui::Render();
    // Rendering code...
}

```

## Summary

- **Enable debug flags** in `ImGuiIO` during initialization to activate `ConfigDebugShowMetrics`, `ConfigDebugShowDebugLog`, and `ConfigDebugIsDebuggerPresent`
- **Use `ShowDemoWindow()`** to access the Debug menu, or call specific debug window functions directly
- **Leverage the Item Picker** to break into your debugger with a single click when `ConfigDebugIsDebuggerPresent` is enabled
- **Install debugger visualizers** from `misc/debuggers/` to inspect ImGui containers in Visual Studio, GDB, or LLDB
- **Utilize `IM_ASSERT` and `IM_DEBUG_BREAK()`** for runtime validation and immediate breakpoint triggers

## Frequently Asked Questions

### How do I view the ID stack for a specific widget in Dear ImGui?

Open the **ID Stack Tool** window via `ImGui::ShowIDStackToolWindow()` or through the Debug menu in the demo window. Hover over any widget to see its complete ID hierarchy in the tool window, which helps resolve ID collisions and understand why input queries fail.

### Can I use Dear ImGui debugging tools in a release build?

While possible, it is not recommended. Debug features like `ConfigDebugIsDebuggerPresent` and the Item Picker are designed for development. The `IM_ASSERT` macros typically compile to nothing in release builds (unless you override `IM_ASSERT`), and debug windows add CPU overhead by tracking detailed statistics.

### Where are the debugger visualizer files located in the ImGui repository?

Platform-specific debugger files reside in `misc/debuggers/`. Use `imgui.natvis` for Visual Studio, `imgui.gdb` for GDB, and [`imgui_lldb.py`](https://github.com/ocornut/imgui/blob/main/imgui_lldb.py) for LLDB. These files provide custom visualizations for `ImVector`, `ImDrawList`, and other internal structures.

### What is the difference between `IM_ASSERT` and `IM_DEBUG_BREAK`?

`IM_ASSERT(condition)` checks a condition and breaks only if it fails, similar to standard assert macros. `IM_DEBUG_BREAK()` unconditionally triggers a debugger breakpoint regardless of state. Both are defined in [`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h) and map to platform-specific breakpoint instructions.