<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Programming on The Emacs Cat</title>
    <link>https://olddeuteronomy.github.io/tags/programming/</link>
    <description>Recent content in Programming on The Emacs Cat</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 04 Aug 2026 11:47:40 +0300</lastBuildDate>
    <atom:link href="https://olddeuteronomy.github.io/tags/programming/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Debugging in Emacs</title>
      <link>https://olddeuteronomy.github.io/post/debugging-in-emacs/</link>
      <pubDate>Tue, 04 Aug 2026 11:47:40 +0300</pubDate>
      <guid>https://olddeuteronomy.github.io/post/debugging-in-emacs/</guid>
      <description>&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;&#xA;&lt;p&gt;In my years of using Emacs, I’ve noticed a common pattern: developers&#xA;who are highly proficient at editing source code in Emacs switch to a&#xA;&amp;ldquo;normal IDE&amp;rdquo; (as they call it)&amp;mdash;such as CLion or Visual Studio&amp;mdash;when&#xA;they need to debug their code. They usually explain this by saying&#xA;that Emacs feels a bit weird for the task.&lt;/p&gt;&#xA;&lt;p&gt;However, I’d much rather not leave Emacs if something &lt;em&gt;can&lt;/em&gt; be done inside it.&lt;/p&gt;&#xA;&lt;p&gt;In this post, I’ll try to show that debugging in Emacs is both simple&#xA;and effective, especially after a few small adjustments to the default&#xA;settings.&lt;/p&gt;&#xA;&lt;p&gt;Debugging in Emacs revolves around two key components:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.sourceware.org/gdb/&#34;&gt;&lt;strong&gt;GDB&lt;/strong&gt;&lt;/a&gt; (GNU Debugger), the most&#xA;popular and powerful debugger for C, C++, and other languages.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.gnu.org/software/emacs/manual/html_node/emacs/Debuggers.html&#34;&gt;&lt;strong&gt;GUD&lt;/strong&gt;&lt;/a&gt;&#xA;(Grand Unified Debugger), Emacs&amp;rsquo; built-in interface since at least&#xA;v19 that turns GDB into a well-integrated debugging environment&#xA;inside Emacs, allowing you to debug your code without leaving the&#xA;editor.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;a-sample-debug-session&#34;&gt;A Sample Debug Session&lt;/h2&gt;&#xA;&lt;p&gt;Below is an example of a typical debug session of mine.&lt;/p&gt;&#xA;&lt;p&gt;In Emacs, I open a source code file (&lt;code&gt;timepoint.c&lt;/code&gt; in this example) and&#xA;run &lt;code&gt;M-x gdb&lt;/code&gt;. GDB then prompts in the minibuffer for the path to the&#xA;corresponding executable, as shown below.&lt;/p&gt;&#xA;&lt;figure&gt;&lt;a href=&#34;https://olddeuteronomy.github.io/img/gud-gdb.png&#34;&gt;&lt;img src=&#34;https://olddeuteronomy.github.io/img/gud-gdb.png&#34;/&gt;&lt;/a&gt;&lt;figcaption&gt;&#xA;            &lt;h4&gt;Loading a program to debug. Click or tap to view the full-size picture.&lt;/h4&gt;&#xA;        &lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;After you enter the path to the executable&amp;mdash;assuming it was built&#xA;with the &lt;code&gt;-g&lt;/code&gt; flag (i.e., compiled with debug information)&amp;mdash;and press&#xA;&lt;!-- raw HTML omitted --&gt;Enter&lt;!-- raw HTML omitted --&gt;, GDB prints some initial output and may ask whether&#xA;it should automatically download missing debugging information from&#xA;trusted online servers.&lt;/p&gt;&#xA;&lt;figure&gt;&lt;a href=&#34;https://olddeuteronomy.github.io/img/gud-debuginfo.png&#34;&gt;&lt;img src=&#34;https://olddeuteronomy.github.io/img/gud-debuginfo.png&#34;/&gt;&lt;/a&gt;&lt;figcaption&gt;&#xA;            &lt;h4&gt;Downloading missing debugging information. Click or tap to view the full-size picture.&lt;/h4&gt;&#xA;        &lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Because I don&amp;rsquo;t intend to debug system or third-party libraries, I&#xA;simply press &lt;!-- raw HTML omitted --&gt;n&lt;!-- raw HTML omitted --&gt; to skip this step, which can occasionally&#xA;freeze Emacs for a while.&lt;/p&gt;&#xA;&lt;p&gt;The GUD &lt;em&gt;dashboard&lt;/em&gt; appears. It usually consists of nine windows.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Debugger&lt;/strong&gt;, the GUD interaction buffer (or GDB shell);&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;C/&lt;/strong&gt;*, the source code buffer;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Frames&lt;/strong&gt;, the stack buffer, a list of stack frames of the program being debugged;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Locals&lt;/strong&gt;, the local variables/registers buffer;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Inferior I/O&lt;/strong&gt;, the input/output buffer (usually associated with &lt;code&gt;stdin&lt;/code&gt;/&lt;code&gt;stdout&lt;/code&gt;);&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Breakpoints&lt;/strong&gt;, the breakpoints/threads list.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;figure&gt;&lt;a href=&#34;https://olddeuteronomy.github.io/img/gud-dashboard.png&#34;&gt;&lt;img src=&#34;https://olddeuteronomy.github.io/img/gud-dashboard.png&#34;/&gt;&lt;/a&gt;&lt;figcaption&gt;&#xA;            &lt;h4&gt;GUD dashboard. Click or tap to view the full-size picture.&lt;/h4&gt;&#xA;        &lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;In my usual workflow, I type &lt;code&gt;break main&lt;/code&gt; (or simply &lt;code&gt;b main&lt;/code&gt;) in the GUD&#xA;interaction buffer (&lt;strong&gt;Debugger&lt;/strong&gt;) to set a breakpoint at the start of my&#xA;program.&lt;/p&gt;&#xA;&lt;figure&gt;&lt;a href=&#34;https://olddeuteronomy.github.io/img/gud-bmain.png&#34;&gt;&lt;img src=&#34;https://olddeuteronomy.github.io/img/gud-bmain.png&#34;/&gt;&lt;/a&gt;&lt;figcaption&gt;&#xA;            &lt;h4&gt;Setting initial breakpoint. Click or tap to view the full-size picture.&lt;/h4&gt;&#xA;        &lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;The new breakpoint shows up right away: as a red fringe marker next to&#xA;the line in the source buffer (color varies by theme) and as an entry&#xA;in the breakpoints list.&lt;/p&gt;&#xA;&lt;p&gt;Now you can type &lt;code&gt;run&lt;/code&gt; in the GUD interaction buffer. Execution will&#xA;then stop at the first breakpoint (line 20 in this example).&lt;/p&gt;&#xA;&lt;h3 id=&#34;gud-keybindings&#34;&gt;GUD Keybindings&lt;/h3&gt;&#xA;&lt;p&gt;Frankly, I find the &lt;a href=&#34;https://www.gnu.org/software/emacs/manual/html_node/emacs/Commands-of-GUD.html&#34;&gt;default GUD keybindings&lt;/a&gt; somewhat complex. For&#xA;example, &lt;code&gt;C-x C-a C-n&lt;/code&gt; is the globally defined key chord for &lt;code&gt;gud-next&lt;/code&gt; &amp;mdash; one&#xA;of the most frequently used debugging commands. Having to type&#xA;three keys while holding the &lt;!-- raw HTML omitted --&gt;Ctrl&lt;!-- raw HTML omitted --&gt; key feels excessive to me, so I&#xA;prefer a single keystroke for this operation.&lt;/p&gt;&#xA;&lt;p&gt;So, in my &lt;code&gt;~/.emacs&lt;/code&gt;, I’ve rebound the most frequently used&#xA;GUD commands to &lt;!-- raw HTML omitted --&gt;F6&lt;!-- raw HTML omitted --&gt; and its derivatives.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(global-set-key [(f6)] &lt;span style=&#34;color:#a6e22e&#34;&gt;#&amp;#39;&lt;/span&gt;gud-next) &lt;span style=&#34;color:#75715e&#34;&gt;;; Execute the next single line.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(global-set-key [(control f6)] &lt;span style=&#34;color:#a6e22e&#34;&gt;#&amp;#39;&lt;/span&gt;gud-step) &lt;span style=&#34;color:#75715e&#34;&gt;;; Enter the called function.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(global-set-key [(shift f6)] &lt;span style=&#34;color:#a6e22e&#34;&gt;#&amp;#39;&lt;/span&gt;gud-cont) &lt;span style=&#34;color:#75715e&#34;&gt;;; Continue execution until hitting a breakpoint.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(global-set-key [(control shift f6)] &lt;span style=&#34;color:#a6e22e&#34;&gt;#&amp;#39;&lt;/span&gt;gud-print) &lt;span style=&#34;color:#75715e&#34;&gt;;; Evaluate the expression at point.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;ve kept the default keybindings for the less frequently used&#xA;commands, such as setting a breakpoint (&lt;code&gt;gud-break&lt;/code&gt;, &lt;code&gt;C-x C-a C-b&lt;/code&gt;),&#xA;continuing execution to the current line (&lt;code&gt;gud-until&lt;/code&gt;, &lt;code&gt;C-x C-a C-u&lt;/code&gt;), and&#xA;so on.&lt;/p&gt;&#xA;&lt;p&gt;Additionally, I’ve added a new keybinding for &lt;code&gt;gud-watch&lt;/code&gt; (&lt;code&gt;C-x C-a C-w&lt;/code&gt;),&#xA;which watches the expression at point. This command has no default&#xA;keybinding in GUD, at least in Emacs 29.3.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-elisp&#34; data-lang=&#34;elisp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(global-set-key (kbd &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;C-x C-a C-w&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;#&amp;#39;&lt;/span&gt;gud-watch) &lt;span style=&#34;color:#75715e&#34;&gt;;; Watch the expression at point.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;debugging&#34;&gt;Debugging&lt;/h3&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s continue with our sample debugging session.&lt;/p&gt;&#xA;&lt;p&gt;We stopped at line 20, the first breakpoint in my program. Now I want&#xA;to step through the function &lt;code&gt;print_timepoint&lt;/code&gt; line by line. In the&#xA;source code buffer, I move the cursor to line 9 and set a new&#xA;breakpoint with &lt;code&gt;C-x C-a C-b&lt;/code&gt; (&lt;code&gt;gud-break&lt;/code&gt;). Then I continue execution&#xA;with &lt;!-- raw HTML omitted --&gt;Shift&lt;!-- raw HTML omitted --&gt;+&lt;!-- raw HTML omitted --&gt;F6&lt;!-- raw HTML omitted --&gt; (&lt;code&gt;gud-cont&lt;/code&gt;) until the new&#xA;breakpoint is hit.&lt;/p&gt;&#xA;&lt;p&gt;After stepping through the function line by line with &lt;!-- raw HTML omitted --&gt;F6&lt;!-- raw HTML omitted --&gt;&#xA;(&lt;code&gt;gud-next&lt;/code&gt;) until the end (line 16), I get the following output:&lt;/p&gt;&#xA;&lt;figure&gt;&lt;a href=&#34;https://olddeuteronomy.github.io/img/gud-step.png&#34;&gt;&lt;img src=&#34;https://olddeuteronomy.github.io/img/gud-step.png&#34;/&gt;&lt;/a&gt;&lt;figcaption&gt;&#xA;            &lt;h4&gt;Debugging a function. Click or tap to view the full-size picture.&lt;/h4&gt;&#xA;        &lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;In the &lt;strong&gt;Locals&lt;/strong&gt; buffer, you can see all local variables and their&#xA;current values. The &lt;strong&gt;Inferior I/O&lt;/strong&gt; buffer shows the program output.&#xA;Everything looks correct: the tpoint variable has the value 0, which&#xA;corresponds to the beginning of the Unix epoch (January 1, 1970).&lt;/p&gt;&#xA;&lt;p&gt;Indeed, we could have inspected the &lt;code&gt;print_timepoint&lt;/code&gt; function by simply&#xA;stepping into it (&lt;code&gt;gud-step&lt;/code&gt;, &lt;!-- raw HTML omitted --&gt;Ctrl&lt;!-- raw HTML omitted --&gt;+&lt;!-- raw HTML omitted --&gt;F6&lt;!-- raw HTML omitted --&gt;) directly&#xA;from the first line of main, where the initial breakpoint was set. I&#xA;used this example to demonstrate more GUD commands in action.&lt;/p&gt;&#xA;&lt;p&gt;Now we can quit the debugging session by typing &lt;code&gt;quit&lt;/code&gt; (or simply &lt;code&gt;q&lt;/code&gt;) in&#xA;the GUD interaction buffer (&lt;strong&gt;Debugger&lt;/strong&gt;).&lt;/p&gt;&#xA;&lt;p&gt;Of course, there’s no way to cover all the functions and commands&#xA;available in GDB/Emacs GUD in one short post but I hope it provides a&#xA;helpful introduction to using Emacs GUD for debugging your code.&lt;/p&gt;&#xA;&lt;p&gt;You can find more information in the &lt;a href=&#34;https://www.gnu.org/software/emacs/manual/html_node/emacs/Debuggers.html&#34;&gt;Running Debuggers Under Emacs&lt;/a&gt; manual;&#xA;the &lt;a href=&#34;https://darkdust.net/files/GDB%20Cheat%20Sheet.pdf&#34;&gt;GDB Cheat Sheet (PDF)&lt;/a&gt; is also worth having on hand.&lt;/p&gt;&#xA;&lt;p&gt;Happy debugging in Emacs!&lt;/p&gt;&#xA;&lt;p&gt;&amp;mdash; The Emacs Cat.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
