|
| 1 | +--- |
| 2 | +name: debug-code |
| 3 | +description: Trace and explain the root cause of a bug in the C++17 Graphitti code |
| 4 | +agent: agent |
| 5 | +tools: ["search", "read"] |
| 6 | +--- |
| 7 | + |
| 8 | +# Inputs and Context |
| 9 | + |
| 10 | +Use the following inputs as the primary source of truth for expected vs. actual behavior. Treat them as ground truth unless you explicitly state otherwise in your assumptions. |
| 11 | + |
| 12 | +- **Problem description from the user (required):** |
| 13 | + |
| 14 | + ${input:problemDescription} |
| 15 | + |
| 16 | +- **Target code (optional selection from the editor):** |
| 17 | + |
| 18 | + ${selection} |
| 19 | + |
| 20 | +- **Steps to reproduce (optional):** |
| 21 | + |
| 22 | + ${input:stepsToReproduce} |
| 23 | + |
| 24 | +- **Logs, stack traces, or failing test output (optional):** |
| 25 | + |
| 26 | + ${input:logs} |
| 27 | + |
| 28 | +- **Environment / configuration details (optional):** |
| 29 | + |
| 30 | + ${input:environment} |
| 31 | + |
| 32 | +If any of these are missing or incomplete, call that out explicitly in the **Assumptions and Scope** section instead of silently guessing. |
| 33 | + |
| 34 | +# Step 1: Understand the Code and Problem |
| 35 | + |
| 36 | +Before proposing any fix, read and summarize the target code and the reported behavior. Answer these questions internally (do not output them): |
| 37 | + |
| 38 | +1. **What is the primary function, method, or code path under suspicion?** Is this a class (`Graph`, `Vertex`), a free function, or a template? |
| 39 | +2. **What is the expected behavior versus the actual behavior?** Include inputs, outputs, and any side effects. |
| 40 | +3. **What dependencies does it have?** Other Graphitti classes, standard library containers, external libraries? |
| 41 | +4. **What invariants or assumptions are relevant?** (e.g., "vertex count must equal the size of the adjacency list", "counter should increase by exactly 1"). |
| 42 | +5. **What categories of bug are most likely?** (logic error, off-by-one, stale or shared state, wrong constant, incorrect default, misuse of a dependency, etc.). |
| 43 | + |
| 44 | +Use the **Inputs and Context** section above as your starting point. Do **not** output your answers to these questions directly. Use them only to guide the trace and explanation in later steps. |
| 45 | + |
| 46 | +# Step 2: Trace the Execution Path |
| 47 | + |
| 48 | +Now that you understand the problem, trace how the code executes from the entry point of the bug to the final incorrect result. |
| 49 | + |
| 50 | +Use the `search` and `read` tools to locate and inspect any relevant files, definitions, and call sites in the Graphitti codebase (for example, where a method is defined and where it is called). |
| 51 | + |
| 52 | +Design an internal execution trace that answers: |
| 53 | + |
| 54 | +1. Which public or entry-point function is called when this bug occurs? |
| 55 | +2. Which functions, methods, or constructors are invoked along the way (including helpers, virtual overrides, and templates)? |
| 56 | +3. How do the key values change at each step (inputs, member variables, return values, accumulators, caches)? |
| 57 | +4. Which branches or conditions are taken in the failing scenario? |
| 58 | +5. Where is the first point at which the state diverges from what is expected? |
| 59 | + |
| 60 | +Do not output this raw trace verbatim. In the next step, you will convert it into a clear explanation for the user. |
| 61 | + |
| 62 | +When exploring the repository: |
| 63 | + |
| 64 | +- Only reference functions, classes, and files that you have actually located with `search` / `read`. |
| 65 | +- If you cannot find a symbol, file, or configuration that seems important, note this as a limitation in **Assumptions and Scope** rather than inventing its behavior. |
| 66 | + |
| 67 | +# Step 3: Explain the Root Cause and Fix |
| 68 | + |
| 69 | +Using the analysis from Step 1 and the trace from Step 2, generate a structured debugging report following these rules: |
| 70 | + |
| 71 | +## Project Conventions |
| 72 | + |
| 73 | +- Organize the answer into the following sections, in this exact order: |
| 74 | + 1. **Problem Summary** — Restate the bug in 1–3 sentences, including the relevant function(s) and the expected vs. actual behavior. |
| 75 | + 2. **Assumptions and Scope** — Briefly list any assumptions you are making about inputs, configuration, or environment, including any missing information from the Inputs and Context section. |
| 76 | + 3. **Execution Trace** — Summarize the key steps in the call chain that lead to the incorrect result, focusing on functions, important state changes, and branches taken. |
| 77 | + 4. **Root Cause Analysis** — Explain precisely _why_ the bug happens, referencing specific functions, conditions, or state transitions. |
| 78 | + 5. **Proposed Fix** — Describe a minimal, targeted change that would correct the behavior, including a concrete code snippet or patch-style suggestion when appropriate. |
| 79 | + 6. **Verification Steps** — Outline how to verify the fix (existing tests to run, new tests to add, and any manual steps). |
| 80 | + |
| 81 | +- In **Execution Trace**, summarize only the essential steps, state changes, and branches relevant to the failing scenario. Avoid line-by-line commentary or speculative paths that are not actually taken when the bug occurs. |
| 82 | +- Only reference functions, classes, files, and configuration values that you have actually seen in the repository or in the provided inputs. If something is inferred or assumed, make that explicit in **Assumptions and Scope**. |
| 83 | +- If there are multiple plausible root causes or the available information is incomplete, clearly: |
| 84 | + - Identify the most likely root cause first. |
| 85 | + - List alternative possibilities as secondary hypotheses, along with what extra data would be needed to confirm or reject them. |
| 86 | +- Use concise paragraphs and bullet points. Avoid long, unstructured walls of text. |
| 87 | +- When referencing functions or methods, include both the name and file path where possible (e.g., ``Counter::increment` in `Simulator/Utils/Counter.cpp``). |
| 88 | + |
| 89 | +## File Placement |
| 90 | + |
| 91 | +- You are **not** required to create or edit files directly in this prompt. Focus on analysis and explanation. |
| 92 | +- When you propose code changes, show them as **snippets** the user can apply manually, rather than editing files yourself. |
| 93 | +- If you reference tests or new test files, follow the existing project structure: |
| 94 | + - Unit tests live under `Testing/UnitTesting/`. |
| 95 | + - For functions touched by the fix, you may suggest using the `/generate-unit-tests` prompt on the affected code to create new tests that reproduce the bug and guard against regressions. |
| 96 | + |
| 97 | +## Code Style |
| 98 | + |
| 99 | +- Keep code examples minimal and focused on the bug and its fix. |
| 100 | +- Use C++17 features and the project’s conventions when writing example code (e.g., `auto` where appropriate, no `using namespace std;`). |
| 101 | +- When showing a fix, include only the smallest necessary surrounding context (e.g., the function signature plus the corrected lines). |
| 102 | +- Add brief inline comments explaining _why_ the fix works, especially when adjusting constants, conditions, or state transitions. |
| 103 | + |
| 104 | +## Few-Shot Example |
| 105 | + |
| 106 | +Below is an example of the expected output format. Match this style exactly, adapting it to the actual bug and code under analysis. |
| 107 | + |
| 108 | +**Input:** Problem description — “`Counter::increment()` always returns 2 when it should return 1 after a single call.” The user selects the implementation of `Counter::increment()` and its helper `internalAdd`. |
| 109 | + |
| 110 | +**Output:** |
| 111 | + |
| 112 | +````md |
| 113 | +1. Problem Summary |
| 114 | + |
| 115 | +`Counter::increment()` increases the internal counter by 2 instead of 1 on a single call. |
| 116 | +Expected: calling `increment()` once from an initial count of 0 should yield 1. |
| 117 | +Actual: the count becomes 2. |
| 118 | + |
| 119 | +2. Assumptions and Scope |
| 120 | + |
| 121 | +- We assume `Counter` starts at 0 unless explicitly initialized otherwise. |
| 122 | +- We focus on the non-thread-safe, single-threaded usage of `Counter`. |
| 123 | +- No external configuration or environment flags modify the increment step. |
| 124 | + |
| 125 | +3. Execution Trace |
| 126 | + |
| 127 | +- Step 1: `Counter::increment()` is called while `count_` is 0 (`Simulator/Utils/Counter.cpp`, ~line 25). |
| 128 | +- Step 2: Inside `increment()`, it calls `internalAdd(2)` instead of `internalAdd(1)`. |
| 129 | +- Step 3: `internalAdd(2)` updates `count_` from 0 to 2 and returns. |
| 130 | +- Step 4: `getCount()` simply returns `count_` without further modification, so the observed result is 2. |
| 131 | + |
| 132 | +4. Root Cause Analysis |
| 133 | + |
| 134 | +The root cause is a hard-coded increment value of 2 inside `Counter::increment()`. |
| 135 | +The intended behavior is to increase the count by exactly 1 per call, but the call to `internalAdd(2)` doubles the expected increment. |
| 136 | +There are no additional side effects or state mutations that compensate for this, so the incorrect value propagates directly to `getCount()`. |
| 137 | + |
| 138 | +5. Proposed Fix |
| 139 | + |
| 140 | +Change the argument passed to `internalAdd` from 2 to 1: |
| 141 | + |
| 142 | +```cpp |
| 143 | +void Counter::increment() { |
| 144 | + // Increment by 1 to match the documented behavior. |
| 145 | + internalAdd(1); |
| 146 | +} |
| 147 | +``` |
| 148 | + |
| 149 | +This ensures a single call to increment() increases count\_ by exactly 1. |
| 150 | + |
| 151 | +6. Verification Steps |
| 152 | + |
| 153 | +Add or update a unit test that: |
| 154 | + |
| 155 | +- Constructs a Counter at 0. |
| 156 | +- Calls increment() once. |
| 157 | +- Asserts that getCount() returns 1. |
| 158 | + |
| 159 | +Run the existing unit test suite (for example, ctest or your standard test command) to confirm no unrelated regressions. |
| 160 | + |
| 161 | +Optionally, use the /generate-unit-tests prompt on Counter to generate additional tests that: |
| 162 | + |
| 163 | +- Call increment() twice and confirm the result is 2. |
| 164 | +- Interleave increment() and decrement() and ensure the count returns to the original value. |
| 165 | +```` |
| 166 | + |
| 167 | +Now generate the debugging report for the target problem and selection. |
0 commit comments