[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[eev] eepitch and GUD

From: Eduardo Ochs
Subject: [eev] eepitch and GUD
Date: Sun, 8 Jul 2007 13:10:57 -0300

Hey eepitch people (Rubikitch, and who else?),

what do you use to run GDB and other GUD-friendly debuggers using
eepitch? After a lot of refactoring I had transformed Rubikitch's
original code into this, that is at:

 (find-eevfile "eev-mini-steps.el" "defvar eepitch-code")


;;;                  _ _       _
;;;   ___  ___ _ __ (_) |_ ___| |__
;;;  / _ \/ _ \ '_ \| | __/ __| '_ \
;;; |  __/  __/ |_) | | || (__| | | |
;;;  \___|\___| .__/|_|\__\___|_| |_|
;;;           |_|

(defvar eepitch-code '(error "eepitch not set up"))
(defvar eepitch-target-buffer nil)

(defun eepitch-prepare-target-buffer ()
"Run `eepitch-code' and store the name of the resulting buffer in
   (eval eepitch-code)
   (setq eepitch-target-buffer (current-buffer))))

(defun eepitch-display-target-buffer ()
 "Display the buffer `eepitch-target-buffer' in another window."
 (if (not (get-buffer-window eepitch-target-buffer))
     (let ((pop-up-windows t)
            (same-window-buffer-names nil))
        (display-buffer eepitch-target-buffer))))

(defun eepitch (code)
"Set the target buffer for pitching lines to; CODE is something like `(shell)'.
To pitch lines to the target buffer, use `\\[eepitch-this-line]'.
As with `eechannel', lines starting with `' are executed as Lisp;
other lines are sent."
 (if (not (listp code))
     (error "eepitch is no longer a macro - quote the code!"))
 (setq eepitch-code code)

(defun eepitch-line (line)
   (select-window (get-buffer-window eepitch-target-buffer))
   (insert line)                              ; "type" the line
   (call-interactively (key-binding "\r"))))  ; then do a RET

(defun eepitch-not-this-buffer ()
 (if (eq (current-buffer) eepitch-target-buffer)
     (error "Can't pitch to the current buffer")))

(defun eepitch-this-line ()
"Pitch this line to the target buffer, or eval it as lisp if it starts
with `'."
 (let ((line (buffer-substring (ee-bol) (ee-eol)))) ; contents of this line
   (if (string-match "^\\(.*\\)" line)             ; lines with a red star
       (ee-eval-string (match-string 1 line))       ; are eval'ed -
     (eepitch-prepare-target-buffer)     ; for other lines reconstruct the
     (eepitch-display-target-buffer)     ; target buffer, display it, make
     (eepitch-not-this-buffer)           ; sure it's a different buffer, and
     (eepitch-line line)))               ; pitch the line to the target.
 (next-line 1))

(defun eepitch-kill ()
 (eepitch-prepare-target-buffer)         ; Prepare (maybe reconstruct) the
 (eepitch-display-target-buffer)         ; target buffer, display it, make
 (eepitch-not-this-buffer)               ; sure it's a different buffer...
 (save-selected-window                   ; Then temporarily switch to the
   (select-window (get-buffer-window eepitch-target-buffer)) ; right window,
   (kill-this-buffer)))          ; and kill the buffer that is there.


but I knew that this wouldn't work for GUD, as I would need a 3-window
setting for it - one window for the e-script, one for the "*gud-prog*"
window, and another one for the program being followed...

Yesterday I experimented with several 3-window configurations, and I
found that this one works (the ascii screenshot was made by hand using
"(format-mode-line mode-line-format 0)" and picture-more and is not
very realistic, but I'm attaching a real screenshot too):

|* (eepitch-gdb-lua-kill)           |#include <lauxlib.h>              |
|* (eepitch-gdb-lua)                |#include <stdio.h>                |
|set args /tmp/loadso.lua           |static int my_foo(lua_State* L) { |
|# br main                          @  int n = lua_gettop(L);          |
|tbr ll_loadlib                     |  int isnum = lua_isnumber(L, 1); |
|run                                |  int m = lua_tonumber(L, 1);     |
|n                                  |  printf("Hi hi!\n");             |
|n                                  |  printf("%d %d %d!\n", n, isnum, |
|p path                             |  return 0;                       |
|p init                             |}                                 |
|n                                  |LUALIB_API int my_init(lua_State *+
|br my_foo                          |  lua_register(L, "foo", my_foo); |
|cont                               |  return 0;                       |
|                                   |}                                 |
|                                   |                                  |
|-:**  TODO  Bot L3255  (Fundamental|                                  |
|Current directory is /home/edrx/usr+                                  |
|GNU gdb 6.6-debian                 |                                  |
|Copyright (C) 2006 Free Software Fo+                                  |
|..blablabla..                      |                                  |
|(gdb) set args /tmp/loadso.lua     |                                  |
|(gdb) br ll_loadlib                |                                  |
|Breakpoint 1 at 0x806bcd8: file loa+                                  |
|(gdb) run                          |                                  |
|Starting program: /home/edrx/usrc/l+                                  |
|Breakpoint 1, ll_loadlib (L=0x80710+                                  |
|(gdb) n                            |                                  |
|(gdb) n                            |                                  |
|(gdb) p path                       |                                  |
|$1 = 0x8082310 "/tmp/"        |                                  |
|(gdb) p init                       |                                  |
|$2 = 0x8081a68 "my_init"           |                                  |
|(gdb) n                            |                                  |
|(gdb) br my_foo                    |                                  |
|Breakpoint 2 at 0xb7ef4602: file so+                                  |
|(gdb) cont                         |                                  |
|Continuing.                        |                                  |
|Breakpoint 2, my_foo (L=0x8071008) |                                  |
|(gdb)                              |                                  |
|                                   |                                  |
|--:**  *gud-lua_O0*  All L33  (Debu|--:--  so.c  All L17  (C/l Abbrev)|

The code for eepitch-gdb-lua-kill and eepitch-gdb-lua is here:

   (defun eepitch-gdb (buffer-name gdb-prog-and-args)
     (other-window 1)
     (if (get-buffer buffer-name)
         (find-ebuffer buffer-name)
       (gdb gdb-prog-and-args)
       (eegud-keys-mode 1))
     (other-window 2)
     (setq eepitch-code `(find-ebuffer ,buffer-name)))

   (defun eepitch-gdb-kill (buffer-name)
     (if (get-buffer buffer-name) (kill-buffer buffer-name))

   (defun eepitch-gdb-lua ()
     (eepitch-gdb "*gud-lua_O0*"
                  "gdb --annotate=3 ~/usrc/lua-5.1.2/src/lua_O0"))

   (defun eepitch-gdb-lua-kill ()
     (eepitch-gdb-kill "*gud-lua_O0*"))

I also changed one of the bindings in eegud-keys-mode:

   (define-key eegud-keys-mode-map "\M-k" 'eegud-kill-this-buffer)

   (defun eegud-kill-this-buffer ()

and the bizarre name of the GUD buffer - "*gud-lua_O0*" - is because
the binary that GDB is debugging is called "lua_O0". GDB (6.6, from
Debian unstable) was giving messages like "variable optimized away"
when I tried to examine the variables "path" and "init", so I changed
my build script for Lua to build two separate binaries, "lua_O0",
compiled with "-g -O0", and "lua", compiled with "-g -O2".

Any comments or suggestions? As I've said, the code for eepitch-gdb-*
is very fresh, from yesterday, and I haven't played with it enough...
one thing that I need to do now is a way to create breakpoints using
hyperlinks; for example,

#          (find-lua51file "src/lvm.c" "case OP_CLOSE:" 1)
* (ee-tbr '(find-lua51file "src/lvm.c" "case OP_CLOSE:" 1))

in an e-script for GDB the first line is a comment; it's a hyperlink.
The second line starts with a red star, and when we pitch it with F8
the ee-tbr follows the hyperlink - with save-excursion - and sets a
temporary breakpoint at that line. I haven't implemented this yet.

   Eduardo Ochs

Attachment: eepitch-gdb.png
Description: PNG image

reply via email to

[Prev in Thread] Current Thread [Next in Thread]