As well as the command-line debugger, mdb, there is also an Emacs interface to this debugger. Note that the Emacs interface only works with GNU Emacs, not with XEmacs.
With the Emacs interface, the debugger will display your source code as you trace through it, marking the line that is currently being executed, and allowing you to easily set breakpoints on particular lines in your source code. You can have separate windows for the debugger prompt, the source code being executed, and for the output of the program being executed. In addition, most of the mdb commands are accessible via menus.
To start the Emacs interface, you first need to put the following text in the file .emacs in your home directory, replacing “/usr/local/mercury-1.0” with the directory that your Mercury implementation was installed in.
(setq load-path (cons (expand-file-name "/usr/local/mercury-1.0/lib/mercury/elisp") load-path)) (autoload 'mdb "gud" "Invoke the Mercury debugger" t)
Build your program with debugging enabled, as described in Quick overview or Preparing a program for debugging. Then start up Emacs, e.g. using the command ‘emacs’, and type M-x mdb RET. Emacs will then prompt you for the mdb command to invoke
Run mdb (like this): mdb
and you should type in the name of the program that you want to debug and any arguments that you want to pass to it:
Run mdb (like this): mdb ./hello arg1 arg2 …
Emacs will then create several “buffers”: one for the debugger prompt, one for the input and output of the program being executed, and one or more for the source files. By default, Emacs will split the display into two parts, called “windows”, so that two of these buffers will be visible. You can use the command C-x o to switch between windows, and you can use the command C-x 2 to split a window into two windows. You can use the “Buffers” menu to select which buffer is displayed in each window.
If you’re using X-Windows, then it is a good idea to set the Emacs variable ‘pop-up-frames’ to ‘t’ before starting mdb, since this will cause each buffer to be displayed in a new “frame” (i.e. a new X window). You can set this variable interactively using the ‘set-variable’ command, i.e. M-x set-variable RET pop-up-frames RET t RET. Or you can put ‘(setq pop-up-frames t)’ in the .emacs file in your home directory.
For more information on buffers, windows, and frames, see the Emacs documentation.
Another useful Emacs variable is ‘gud-mdb-directories’. This specifies the list of directories to search for source files. You can use a command such as
M-x set-variable RET gud-mdb-directories RET (list "/foo/bar" "../other" "/home/guest") RET
to set it interactively, or you can put a command like
(setq gud-mdb-directories (list "/foo/bar" "../other" "/home/guest"))
in your .emacs file.
At each trace event, the debugger will search for the source file corresponding to that event, first in the same directory as the program, and then in the directories specified by the ‘gud-mdb-directories’ variable. It will display the source file, with the line number corresponding to that trace event marked by an arrow (‘=>’) at the start of the line.
Several of the debugger features can be accessed by moving the cursor to the relevant part of the source code and then selecting a command from the menu. You can set a break point on a line by moving the cursor to the appropriate line in your source code (e.g. with the arrow keys, or by clicking the mouse there), and then selecting the “Set breakpoint on line” command from the “Breakpoints” sub-menu of the “MDB” menu. You can set a breakpoint on a procedure by moving the cursor over the procedure name and then selecting the “Set breakpoint on procedure” command from the same menu. And you can display the value of a variable by moving the cursor over the variable name and then selecting the “Print variable” command from the “Data browsing” sub-menu of the “MDB” menu. Most of the menu commands also have keyboard short-cuts, which are displayed on the menu.
Note that ‘mdb’’s ‘context’ and ‘user_event_context’ commands should not be used if you are using the Emacs interface, otherwise the Emacs interface won’t be able to parse the file names and line numbers that ‘mdb’ outputs, and so it won’t be able to highlight the correct location in the source code.