0

I often run Gdb in a dedicated Emacs session. I have code to run gdb when Emacs start and set up Many-Windows mode.

For one particular project, there are many programs, all written in C, that share a main() function but where the interesting part is in a separate source file whose base name is the same as the executable: hello is built from hello.c and main.c, foo is built from foo.c and main.c, etc. Gdb sees the main() function in main.c and therefore opens main.c initially, which makes perfect sense. But for this project, main.c is mostly irrelevant and I want to start with the program-specific source file open, e.g. hello.c.

I want to either instruct Gdb to consider a different file to be the “main” source, or instruct Emacs to display a different source file initially.

I wrote the code below to instruct Emacs to display a different source file. It doesn't work, and I don't understand why.

;; Specific code for my project, where the main() function is in a boring
;; file that is shared between many executables and the interesting source
;; file is the one based on the executable name.
;; The code here is simplified from my real code and only works if all the
;; files are in the current directory.
(defvar actual-source-file (concat default-directory "/"
                                   (car command-line-args-left) ".c"))
(defun visit-actual-source ()
  (interactive)
  (gdb-display-source-buffer (find-file-noselect actual-source-file)))
(add-hook 'window-setup-hook 'visit-actual-source)

;; Don't ask for confirmation on exit even if a process is running.
;; This doesn't have any impact on the question, but makes testing easier.
(defun clear-buffer-process-query-on-exit-flag ()
  (let ((proc (get-buffer-process (current-buffer))))
    (if proc
        (set-process-query-on-exit-flag proc nil))))
(defun clear-gdb-inferior-process-query-on-exit-flag ()
  (if (equal (process-name (get-buffer-process (current-buffer))) "gdb-inferior")
      (clear-buffer-process-query-on-exit-flag)))
(add-hook 'comint-exec-hook 'clear-gdb-inferior-process-query-on-exit-flag)
(defadvice gud-common-init
    (after gud-common-init-set-process-query-on-exit-flag activate)
  "Don't ask for confirmation if exiting Emacs during the debug session."
  (clear-buffer-process-query-on-exit-flag))

;; Run gdb.
(let ((command-string (combine-and-quote-strings command-line-args-left)))
  (set-frame-name (concat "gdb: " command-string))
  (gdb (concat "gdb -i=mi --args " command-string)))
(setq command-line-args-left nil)

;; Set up a nice window configuration.
(gdb-many-windows)

Set up a test environment:

cat <<'EOF' >main.c
void do_stuff(void);
int main() {
    do_stuff();
    return 0;
}
EOF
cat <<'EOF' >hello.c
#include <stdio.h>
void do_stuff(void) {
    puts("Hello world");
}
EOF
cc -g -o hello hello.c main.c

Then run Emacs with the Lisp code above in gdb-alternate-source.el.

emacs -q -l gdb-alternate-source.el hello

Desired effect: display the 6 windows of Gdb Many-Windows mode, with hello.c in the middle left window.
Actual effect: display the 6 windows of Gdb Many-Windows mode, with main.c in the middle left window. hello.c is open but not displayed.

If I run M-x visit-actual-source after Emacs starts, it has the desired effect: hello.c becomes displayed instead of main.c.

If I add (recursive-edit) after (gdb-many-windows) or before the call to gdb-display-source-buffer in visit-actual-source, then after I exit the recursive edit, hello.c replaces main.c in the middle left window and *GNU Emacs* (“Welcome to GNU Emacs …”) replaces *gud-hello* in the top left window. On the other hand, adding (force-window-update) or (redisplay) doesn't make any difference.

I guess I need to add some code to update something related to the window configuration, but what? How do I get the desired file displayed automatically when Emacs starts?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.