This is the mail archive of the
gdb@sourceware.cygnus.com
mailing list for the GDB project.
libGDB architecture - Guile interface
- To: gdb@sourceware.cygnus.com
- Subject: libGDB architecture - Guile interface
- From: Martin Baulig <martin@home-of-linux.org>
- Date: 31 Aug 1999 00:02:22 +0200
- Cc: gnome-debugger-list@gnome.org
- References: <37C204C1.E81875D9@cygnus.com>
Andrew Cagney <ac131313@cygnus.com> writes:
> Within libGDB the internal code that described the breakpoint would
> be accessible. In the GUILE case, that internal code would be called
> with a GUILE builder and would construct an object like:
>
> (breakpoint
> ((number 1)
> (type "breakpoint")
> (disp "keep")
> (enabled "y")
> (addr "0x0000003d")
> (func "main")
> (file "hello.c" 3)))
>
Hello,
I've been working on a guile interface to gdb for some time now (which is
in the gdb-guile module in the GNOME CVS cvs tree).
Currently, I'm mostly wrapping around the existing gdb commands by walking
the `cmdlist' and adding a guile command for each entry so we'll have
things like
(gdb-file "~/INSTALL/bin/gnome-hello")
(gdb-break "main")
(gdb-break "test.c 80")
(gdb-run "argument1 argument2 ... argumentn")
Last week (after reading the "libGDB architecture" proposal) I started to
migrate to "real" implementations of these functions (for instance I was
using annotations to get things like a backtrace before).
* * *
This is a short overview about the implementation of `(gdb-frame)' and
`(gdb-backtrace)'.
In module `(gdb structs)' we have the following:
====
(define-public gdb-frame-fields
'(type level file line mid pc function language))
(define-public gdb-frame-rec
(make-record-type "gdb-frame-rec" gdb-frame-fields))
====
The implementation of `(gdb-frame)' uses a custom print_frame_info_base ()
to "build" and return an instance of this `gdb-frame-rec' record:
====
frame = scm_make_struct (scm_gdb_gdb_frame_rec, SCM_MAKINUM (0), SCM_EOL);
if (frame_in_dummy (fi))
{
scm_struct_set_x (frame, frame_rec_itable.type,
scm_sym_called_from_gdb);
scm_struct_set_x (frame, frame_rec_itable.level,
SCM_MAKINUM (level == -1 ? 0 : level));
scm_struct_set_x (frame, frame_rec_itable.pc,
SCM_MAKINUM (fi->pc));
return frame;
}
/* .... later on ...... */
scm_struct_set_x (frame, frame_rec_itable.level,
SCM_MAKINUM (level == -1 ? 0 : level));
scm_struct_set_x (frame, frame_rec_itable.pc,
SCM_MAKINUM (fi->pc));
scm_struct_set_x (frame, frame_rec_itable.function,
scm_makfrom0str (funname ? funname : "??"));
scm_struct_set_x (frame, frame_rec_itable.language,
scm_assq_ref (scm_gdb_languages_alist_2,
SCM_MAKINUM (funlang)));
if (sal.symtab && sal.symtab->filename)
{
scm_struct_set_x (frame, frame_rec_itable.file,
scm_makfrom0str (sal.symtab->filename));
scm_struct_set_x (frame, frame_rec_itable.mid,
gh_bool2scm (fi->pc != sal.pc));
scm_struct_set_x (frame, frame_rec_itable.line,
SCM_MAKINUM (sal.line));
}
return frame;
====
Now, the implementation of `(gdb-frame)' calls this custom
print_frame_info_base () with the selected_frame (raises an
exception when there's no stack) and returns an instance of
this record. The implementation of `(gdb-backtrace)' simply
returns a list of such frame records.
On the client side (gdb_corba_get_backtrace () in guile/stack.c
in the ggdb module in GNOME CVS) I'm currently using
record-accessor's to access to returned data, but I'll change this
to use scm_struct_ref directly (with the positions looked up in
the `gdb-frame-fields') for a better performance.
--
Martin Baulig - martin@home-of-linux.org - http://www.home-of-linux.org