This is the mail archive of the gdb@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

libGDB architecture - Guile interface


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]