public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* guile scripting for gdb
@ 2013-11-04 16:04 Doug Evans
       [not found] ` <87ob5vlr2s.fsf@gnu.org>
  0 siblings, 1 reply; 9+ messages in thread
From: Doug Evans @ 2013-11-04 16:04 UTC (permalink / raw)
  To: gdb-patches, guile-user

Hi.
fyi, I've uploaded my gdb-guile branch to github.

https://github.com/dje42/gdb.git

It's in branch gdb-guile.

It's still very preliminary, there's still lots to do, and there are
some open issues.
If you're interested take a look.
We'll have to see how things end up if/after it passes code review, so
while I welcome all the help I can get, I'd feel bad if people write
too much now only having to redo it.
OTOH, if you have as much fun with this stuff as I do, go for it. :-)

I'll be submitting snippets for review over the coming weeks.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: guile scripting for gdb
       [not found] ` <87ob5vlr2s.fsf@gnu.org>
@ 2013-11-09 19:47   ` Doug Evans
  2013-11-09 19:48     ` Thien-Thi Nguyen
                       ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Doug Evans @ 2013-11-09 19:47 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-user, gdb-patches

On Thu, Nov 7, 2013 at 3:39 PM, Ludovic Courtès <ludo@gnu.org> wrote:
> Hello,
>
> Doug Evans <dje@sebabeach.org> skribis:
>
>> fyi, I've uploaded my gdb-guile branch to github.
>>
>> https://github.com/dje42/gdb.git
>>
>> It's in branch gdb-guile.
>
> Nice piece of work from several angles (implementation strategy, test
> coverage, style, docstrings, comments, etc.)

To be fair, a lot of it derives from the Python version (gdb/python/*.[ch]).

>> It's still very preliminary, there's still lots to do, and there are
>> some open issues.
>
> As discussed on IRC, one possible issue is eq?-ness of SMOBs: one would
> usually expects pointer equality to be preserved at the Scheme level.

Yeah.
That'll require gdb maintaining its own table(s) for each kind of smob
we want to intern.
Definitely doable, though there are some issues.
E.g., while std::vector<int> may be the same type in two different programs,
if we want eq?-ness to survive across the lifetime of the underlying gdb object
then that would take extra effort to make that work.
Would it be ok to punt on eq?-ness until there's a compelling reason
to make it work?
At that point we'd have a better idea of the use-case involved, and data on
the speed improvement eq? would bring to the table in that instance.
And even then we might still have eq?-ness defined by the lifetime of the
underlying gdb object (until there's a compelling reason to then make
that work).

> Another question I had is the lifetime of Scheme objects vs. that of the
> underlying C objects.  AIUI C objects cannot be forcefully kept alive
> when their Scheme representative is live, which is why the bindings have
> this notion of “invalid” object at the Scheme level.  Is it also the way
> the Python bindings deal with the issue?
>
> Random remarks:
>
>   • The disasm interface looks cool.  I think it’d be more convenient if
>     it used records to represent disassembled instructions.

Thanks.  I wanted to make it general so that we could disassemble more
than just code from the program.

I wasn't sure which things to make as records or goops objects or ...
So I'm starting small.
Each disassembly is just immutable data so it's easy enough
to write wrappers to provide the API one wants.

>   • It would be nice to wrap the iterator interface in SRFI-41 streams.

Yeah, I have a TODO to look into that.

> An interesting exercise would be to write pretty-printers for SCM values
> and tools to walk Guile’s VM stack (like Guile’s gdbinit attempts to do).

Agreed, excellent exercises.

gdb has a "frame filter" interface that's intended to be used to
implement multi-language backtraces.
Need to add a gdb/guile interface.
I'm not sure how Guile's new VM changes things - someone may want to
write one for 2.0 and one for 2.2.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: guile scripting for gdb
  2013-11-09 19:47   ` Doug Evans
@ 2013-11-09 19:48     ` Thien-Thi Nguyen
  2013-11-10  6:26     ` Doug Evans
  2013-11-11  1:50     ` Ludovic Courtès
  2 siblings, 0 replies; 9+ messages in thread
From: Thien-Thi Nguyen @ 2013-11-09 19:48 UTC (permalink / raw)
  To: Doug Evans; +Cc: Ludovic Courtès, guile-user, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1460 bytes --]

() Doug Evans <dje@sebabeach.org>
() Sat, 9 Nov 2013 10:40:18 -0800

   Would it be ok to punt on eq?-ness until there's a compelling reason
   to make it work?

Does the non-‘eq?’-ness of smobs prevent them from retaining object
properties, here?  This is the long-standing bug that GNU Serveez is
addressing (in the next release):

 http://git.savannah.gnu.org/cgit/serveez.git?h=p

by keeping a hash of all smobs, keyed on the underlying C object
address, and requiring the C layer to inform the Guile glue code when
the C object is about to be freed (a degenerate "observer pattern").

We are able to do this only because two of the types are in the glue
code (no special hooks needed) and the one hook necessary for the type
"internally" managed by libserveez is easy to add because we control the
libserveez API.

Anyway, however one chooses to do it (i am open to suggestions on how to
do it better, btw!), the benefit to the user is that:

 (define prop (make-object-property))
 (set! (prop OBJ) VALUE)

works "normally, as expected" for OBJ == smob wrapping the "same C
object", as well as any other.  (One less thing to worry about.)
For GNU Serveez, at least, this is compelling enough.

-- 
Thien-Thi Nguyen
   GPG key: 4C807502
   (if you're human and you know it)
      read my lisp: (responsep (questions 'technical)
                               (not (via 'mailing-list)))
                     => nil

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: guile scripting for gdb
  2013-11-09 19:47   ` Doug Evans
  2013-11-09 19:48     ` Thien-Thi Nguyen
@ 2013-11-10  6:26     ` Doug Evans
  2013-11-11  1:50     ` Ludovic Courtès
  2 siblings, 0 replies; 9+ messages in thread
From: Doug Evans @ 2013-11-10  6:26 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-user, gdb-patches

On Sat, Nov 9, 2013 at 10:40 AM, Doug Evans <dje@sebabeach.org> wrote:
>> As discussed on IRC, one possible issue is eq?-ness of SMOBs: one would
>> usually expects pointer equality to be preserved at the Scheme level.
>
> Yeah.
> That'll require gdb maintaining its own table(s) for each kind of smob
> we want to intern.

Actually, to be more precise, it will require maintaining tables for
*some* smobs we want to intern.
For other smobs the cost of caching the SCM in the gdb object isn't onerous.
[The object is marked as protected from GC until the gdb object is deleted.]

Alas, for two of the more important smobs we'd want to eq?, I think,
gdb symbols and types, we'll need separate tables.
Minimizing space usage of their gdb structs is important (critical
even), and only a small fraction of them will typically be used in
Scheme.
And we certainly don't want to pay that expense when Scheme isn't used.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: guile scripting for gdb
  2013-11-09 19:47   ` Doug Evans
  2013-11-09 19:48     ` Thien-Thi Nguyen
  2013-11-10  6:26     ` Doug Evans
@ 2013-11-11  1:50     ` Ludovic Courtès
  2013-11-11  6:28       ` Doug Evans
  2 siblings, 1 reply; 9+ messages in thread
From: Ludovic Courtès @ 2013-11-11  1:50 UTC (permalink / raw)
  To: Doug Evans; +Cc: guile-user, gdb-patches

Doug Evans <dje@sebabeach.org> skribis:

> On Thu, Nov 7, 2013 at 3:39 PM, Ludovic Courtès <ludo@gnu.org> wrote:

[...]

>> As discussed on IRC, one possible issue is eq?-ness of SMOBs: one would
>> usually expects pointer equality to be preserved at the Scheme level.
>
> Yeah.
> That'll require gdb maintaining its own table(s) for each kind of smob
> we want to intern.
> Definitely doable, though there are some issues.
> E.g., while std::vector<int> may be the same type in two different programs,

What I had in mind was something simpler: suppose you have the very same
C struct pointer reaches the Scheme level, at two different points in
time, or via two different paths; currently gdb may end up allocating
two different SMOBs (i.e., two SMOBs that are not eq?), whereas I would
suggest making sure there’s only one SMOB.

Example:

--8<---------------cut here---------------start------------->8---
(gdb) guile (lookup-type "int")
#<gdb:type int>
(gdb) guile (arch-int-type (current-arch))
#<gdb:type int>
(gdb) guile (eq? (lookup-type "int") (arch-int-type (current-arch)))
#f
--8<---------------cut here---------------end--------------->8---

Here I bet the underlying ‘struct type’ pointer return by ‘lookup-type’
is the same as that returned by ‘arch-int-type’, yet the SMOBs are
different.

Fixing it would require maintaining a C->SMOB mapping.

> if we want eq?-ness to survive across the lifetime of the underlying gdb object
> then that would take extra effort to make that work.
> Would it be ok to punt on eq?-ness until there's a compelling reason
> to make it work?

Yes, a lot can already be done with the current semantics, but at some
point it may break the user’s expectations.  It’s natural to compare
presumably-pointer-identical objects with eq?, or to use eq? hash
tables.

[...]

>> An interesting exercise would be to write pretty-printers for SCM values
>> and tools to walk Guile’s VM stack (like Guile’s gdbinit attempts to do).
>
> Agreed, excellent exercises.
>
> gdb has a "frame filter" interface that's intended to be used to
> implement multi-language backtraces.

That sounds cool.  If gdb could show trace mixing both stacks, that’d be
nice.

> Need to add a gdb/guile interface.
> I'm not sure how Guile's new VM changes things - someone may want to
> write one for 2.0 and one for 2.2.

Yeah, the VM in 2.2 is completely different.

Thanks,
Ludo’.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: guile scripting for gdb
  2013-11-11  1:50     ` Ludovic Courtès
@ 2013-11-11  6:28       ` Doug Evans
  2013-11-11  6:37         ` Doug Evans
  2013-11-11 11:55         ` Ludovic Courtès
  0 siblings, 2 replies; 9+ messages in thread
From: Doug Evans @ 2013-11-11  6:28 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: Doug Evans, guile-user, gdb-patches

On Sun, Nov 10, 2013 at 4:19 PM, Ludovic Courtès <ludo@gnu.org> wrote:
> Doug Evans <dje@sebabeach.org> skribis:
>
>> On Thu, Nov 7, 2013 at 3:39 PM, Ludovic Courtès <ludo@gnu.org> wrote:
>
> [...]
>
>>> As discussed on IRC, one possible issue is eq?-ness of SMOBs: one would
>>> usually expects pointer equality to be preserved at the Scheme level.
>>
>> Yeah.
>> That'll require gdb maintaining its own table(s) for each kind of smob
>> we want to intern.
>> Definitely doable, though there are some issues.
>> E.g., while std::vector<int> may be the same type in two different programs,
>
> What I had in mind was something simpler: suppose you have the very same
> C struct pointer reaches the Scheme level, at two different points in
> time, or via two different paths; currently gdb may end up allocating
> two different SMOBs (i.e., two SMOBs that are not eq?), whereas I would
> suggest making sure there’s only one SMOB.
>
> Example:
>
> --8<---------------cut here---------------start------------->8---
> (gdb) guile (lookup-type "int")
> #<gdb:type int>
> (gdb) guile (arch-int-type (current-arch))
> #<gdb:type int>
> (gdb) guile (eq? (lookup-type "int") (arch-int-type (current-arch)))
> #f
> --8<---------------cut here---------------end--------------->8---
>
> Here I bet the underlying ‘struct type’ pointer return by ‘lookup-type’
> is the same as that returned by ‘arch-int-type’, yet the SMOBs are
> different.
>
> Fixing it would require maintaining a C->SMOB mapping.

I'm pretty sure we have a sufficiently similar idea in mind.
I mention the use of multiple tables because the lifetimes of
different kinds of objects are different, and it may be easier to
delete the table than iterate over each element looking for entries
that need to be deleted.

For reference sake, gdb doesn't guarantee that in the above example
the underlying pointers are equal.
While the arch provides a definition of "int" it can also come from
the debug info in the program (actually there can and typically will
be several copies, one from each .o in the program).
eq-ness will be problematic even with the C->SMOB mapping.

>> if we want eq?-ness to survive across the lifetime of the underlying gdb object
>> then that would take extra effort to make that work.
>> Would it be ok to punt on eq?-ness until there's a compelling reason
>> to make it work?
>
> Yes, a lot can already be done with the current semantics, but at some
> point it may break the user’s expectations.  It’s natural to compare
> presumably-pointer-identical objects with eq?, or to use eq? hash
> tables.

No disagreement there.

> [...]
>
>>> An interesting exercise would be to write pretty-printers for SCM values
>>> and tools to walk Guile’s VM stack (like Guile’s gdbinit attempts to do).
>>
>> Agreed, excellent exercises.
>>
>> gdb has a "frame filter" interface that's intended to be used to
>> implement multi-language backtraces.
>
> That sounds cool.  If gdb could show trace mixing both stacks, that’d be
> nice.
>
>> Need to add a gdb/guile interface.
>> I'm not sure how Guile's new VM changes things - someone may want to
>> write one for 2.0 and one for 2.2.
>
> Yeah, the VM in 2.2 is completely different.
>
> Thanks,
> Ludo’.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: guile scripting for gdb
  2013-11-11  6:28       ` Doug Evans
@ 2013-11-11  6:37         ` Doug Evans
  2013-11-11 13:16           ` Ludovic Courtès
  2013-11-11 11:55         ` Ludovic Courtès
  1 sibling, 1 reply; 9+ messages in thread
From: Doug Evans @ 2013-11-11  6:37 UTC (permalink / raw)
  To: Ludovic Courtès, guile-user, gdb-patches

Doug Evans <xdje42@gmail.com> writes:
> On Sun, Nov 10, 2013 at 4:19 PM, Ludovic Courtès <ludo@gnu.org> wrote:
>> Doug Evans <dje@sebabeach.org> skribis:
>>> On Thu, Nov 7, 2013 at 3:39 PM, Ludovic Courtès <ludo@gnu.org> wrote:
>>>> As discussed on IRC, one possible issue is eq?-ness of SMOBs: one would
>>>> usually expects pointer equality to be preserved at the Scheme level.

I uploaded to my github repo a branch with a prototype of implementing
this for gdb symbols.

https://github.com/dje42/gdb.git
branch: eq-smobs

diff --git a/gdb/guile/guile-internal.h b/gdb/guile/guile-internal.h
index 30abd97..c5bc939 100644
--- a/gdb/guile/guile-internal.h
+++ b/gdb/guile/guile-internal.h
@@ -23,6 +23,7 @@
 #ifndef GDB_GUILE_INTERNAL_H
 #define GDB_GUILE_INTERNAL_H
 
+#include "hashtab.h"
 #include "scripting.h"
 #include "symtab.h"
 #include "libguile.h"
@@ -213,6 +214,12 @@ extern void gdbscm_add_objfile_ref (struct objfile *objfile,
 extern void gdbscm_remove_objfile_ref (struct objfile *objfile,
 				       const struct objfile_data *data_key,
 				       chained_gdb_smob *g_smob);
+
+extern htab_t gdbscm_create_gsmob_ptr_map (htab_hash hash_fn, htab_eq eq_fn);
+
+extern void **gdbscm_find_gsmob_ptr_slot (htab_t htab, void *ptr, int insert);
+
+extern void gdbscm_clear_gsmob_ptr_slot (htab_t htab, void *ptr);
 \f
 /* Exceptions and calling out to Guile.  */
 
diff --git a/gdb/guile/scm-smob.c b/gdb/guile/scm-smob.c
index b342e87..40d8a4c 100644
--- a/gdb/guile/scm-smob.c
+++ b/gdb/guile/scm-smob.c
@@ -395,6 +395,46 @@ gdbscm_remove_objfile_ref (struct objfile *objfile,
   if (g_smob->next)
     g_smob->next->prev = g_smob->prev;
 }
+
+/* Create a hash table for mapping a pointer to a gdb data structure to the
+   gsmob that wraps it.  */
+
+htab_t
+gdbscm_create_gsmob_ptr_map (htab_hash hash_fn, htab_eq eq_fn)
+{
+  htab_t htab = htab_create_alloc (7, hash_fn, eq_fn,
+				   NULL, xcalloc, xfree);
+
+  return htab;
+}
+
+/* Return a pointer to the htab entry for the gsmob wrapping PTR.
+   If INSERT is non-zero, create an entry if one doesn't exist.
+   Otherwise NULL is returned if the entry is not found.  */
+
+void **
+gdbscm_find_gsmob_ptr_slot (htab_t htab, void *ptr, int insert)
+{
+  void **slot = htab_find_slot (htab, ptr, insert ? INSERT : NO_INSERT);
+
+  return slot;
+}
+
+/* Remove PTR from HTAB.
+   PTR is a pointer to a gsmob that wraps a pointer to a GDB datum.
+   This is used, for example, when an object is freed.
+
+   It is an error to call this if PTR is not in HTAB (only because it allows
+   for some consistency checking).  */
+
+void
+gdbscm_clear_gsmob_ptr_slot (htab_t htab, void *ptr)
+{
+  void **slot = htab_find_slot (htab, ptr, NO_INSERT);
+
+  gdb_assert (slot != NULL);
+  htab_clear_slot (htab, slot);
+}
 \f
 /* Initialize the Scheme gsmobs code.  */
 
diff --git a/gdb/guile/scm-symbol.c b/gdb/guile/scm-symbol.c
index 0c9f531..e3122c6 100644
--- a/gdb/guile/scm-symbol.c
+++ b/gdb/guile/scm-symbol.c
@@ -32,14 +32,16 @@
 /* The <gdb:symbol> smob.  */
 
 typedef struct {
-  /* This always appears first.
-     A symbol object is associated with an objfile, so use a chained_gdb_smob
-     to keep track of all symbols associated with the objfile.  This lets us
-     invalidate the underlying struct symbol when the objfile is deleted.  */
-  chained_gdb_smob base;
+  /* This always appears first.  */
+  gdb_smob base;
 
   /* The GDB symbol structure this smob is wrapping.  */
   struct symbol *symbol;
+
+  /* Backlink to our containing SCM.
+     This is used by the eq? machinery: We need to be able to see if we have
+     already created a gsmob for a symbol, and if so use that SCM.  */
+  SCM containing_scm;
 } symbol_smob;
 
 static const char symbol_smob_name[] = "gdb:symbol";
@@ -56,6 +58,46 @@ static const struct objfile_data *syscm_objfile_data_key;
 \f
 /* Administrivia for symbol smobs.  */
 
+/* Helper function to hash a symbol_smob.  */
+
+static hashval_t
+syscm_hash_symbol_smob (const void *p)
+{
+  const symbol_smob *s_smob = p;
+
+  return htab_hash_pointer (s_smob->symbol);
+}
+
+/* Helper function to compute equality of symbol_smobs.  */
+
+static int
+syscm_eq_symbol_smob (const void *ap, const void *bp)
+{
+  const symbol_smob *a = ap;
+  const symbol_smob *b = bp;
+
+  return a->symbol == b->symbol;
+}
+
+/* Return the struct symbol pointer -> SCM mapping table.
+   It is created if necessary.  */
+
+static htab_t
+syscm_objfile_symbol_map (struct symbol *symbol)
+{
+  struct objfile *objfile = SYMBOL_SYMTAB (symbol)->objfile;
+  htab_t htab = objfile_data (objfile, syscm_objfile_data_key);
+
+  if (htab == NULL)
+    {
+      htab = gdbscm_create_gsmob_ptr_map (syscm_hash_symbol_smob,
+					  syscm_eq_symbol_smob);
+      set_objfile_data (objfile, syscm_objfile_data_key, htab);
+    }
+
+  return htab;
+}
+
 /* The smob "mark" function for <gdb:symbol>.  */
 
 static SCM
@@ -63,8 +105,10 @@ syscm_mark_symbol_smob (SCM self)
 {
   symbol_smob *s_smob = (symbol_smob *) SCM_SMOB_DATA (self);
 
+  /* There's no need to mark containing_scm.  */
+
   /* Do this last.  */
-  return gdbscm_mark_chained_gsmob (&s_smob->base);
+  return gdbscm_mark_gsmob (&s_smob->base);
 }
 
 /* The smob "free" function for <gdb:symbol>.  */
@@ -74,11 +118,13 @@ syscm_free_symbol_smob (SCM self)
 {
   symbol_smob *s_smob = (symbol_smob *) SCM_SMOB_DATA (self);
 
-  gdbscm_remove_objfile_ref ((s_smob->symbol != NULL
-			      && SYMBOL_SYMTAB (s_smob->symbol) != NULL)
-			     ? SYMBOL_SYMTAB (s_smob->symbol)->objfile
-			     : NULL,
-			     syscm_objfile_data_key, &s_smob->base);
+  if (s_smob->symbol != NULL)
+    {
+      htab_t htab = syscm_objfile_symbol_map (s_smob->symbol);
+
+      gdbscm_clear_gsmob_ptr_slot (htab, s_smob);
+    }
+
   /* Not necessary, done to catch bugs.  */
   s_smob->symbol = NULL;
 
@@ -133,7 +179,7 @@ syscm_make_symbol_smob (void)
 
   s_smob->symbol = NULL;
   s_scm = scm_new_smob (symbol_smob_tag, (scm_t_bits) s_smob);
-  gdbscm_init_chained_gsmob (&s_smob->base);
+  gdbscm_init_gsmob (&s_smob->base);
 
   return s_scm;
 }
@@ -155,47 +201,44 @@ gdbscm_symbol_p (SCM scm)
 }
 
 /* Create a new <gdb:symbol> object that encapsulates SYMBOL.
-   The new symbol is registered with the life-cycle chain of the
-   associated objfile (if any).  */
-
-SCM
-syscm_gsmob_from_symbol (struct symbol *symbol)
-{
-  SCM s_scm = syscm_make_symbol_smob ();
-  symbol_smob *s_smob = (symbol_smob *) SCM_SMOB_DATA (s_scm);
-
-  gdbscm_add_objfile_ref (SYMBOL_SYMTAB (symbol)
-			  ? SYMBOL_SYMTAB (symbol)->objfile
-			  : NULL,
-			  syscm_objfile_data_key, &s_smob->base);
-  s_smob->symbol = symbol;
-
-  return s_scm;
-}
-
-/* Create a new <gdb:symbol> object that encapsulates SYMBOL.
    The object is passed through *smob->scm*.
    A Scheme exception is thrown if there is an error.  */
 
 SCM
 syscm_scm_from_symbol_unsafe (struct symbol *symbol)
 {
-  /* This doesn't use syscm_gsmob_from_symbol because we don't want to
-     cause any side-effects until we know the conversion worked.  */
-  SCM s_scm = syscm_make_symbol_smob ();
-  symbol_smob *s_smob = (symbol_smob *) SCM_SMOB_DATA (s_scm);
+  htab_t htab;
+  void **slot;
+  SCM s_scm;
+  symbol_smob *s_smob, s_smob_for_lookup;
   SCM result;
 
+  /* If we've already created a gsmob for this symbol, return it.
+     This makes symbols eq?-able.
+     We call gdbscm_find_gsmob_ptr_slot twice because we don't want to leave
+     the side-effect of the INSERT behind if we later throw an exception.  */
+  htab = syscm_objfile_symbol_map (symbol);
+  s_smob_for_lookup.symbol = symbol;
+  slot = gdbscm_find_gsmob_ptr_slot (htab, &s_smob_for_lookup, 0);
+  if (slot != NULL)
+    {
+      s_smob = *slot;
+      return s_smob->containing_scm;
+    }
+
+  s_scm = syscm_make_symbol_smob ();
+  s_smob = (symbol_smob *) SCM_SMOB_DATA (s_scm);
+
   result = gdbscm_scm_from_gsmob_unsafe (s_scm);
 
   if (gdbscm_is_exception (result))
     gdbscm_throw (result);
 
-  gdbscm_add_objfile_ref (SYMBOL_SYMTAB (symbol)
-			  ? SYMBOL_SYMTAB (symbol)->objfile
-			  : NULL,
-			  syscm_objfile_data_key, &s_smob->base);
   s_smob->symbol = symbol;
+  s_smob->containing_scm = result;
+
+  slot = gdbscm_find_gsmob_ptr_slot (htab, s_smob, 1);
+  *slot = s_smob;
 
   return result;
 }
@@ -282,26 +325,33 @@ syscm_get_valid_symbol_arg_unsafe (SCM self, int arg_pos,
   return s_smob->symbol;
 }
 
+/* Helper function for syscm_del_objfile_symbols to mark the symbol
+   as invalid.  */
+
+static int
+syscm_mark_symbol_invalid (void **slot, void *info)
+{
+  symbol_smob *s_smob = (symbol_smob *) *slot;
+
+  s_smob->symbol = NULL;
+  return 1;
+}
+
 /* This function is called when an objfile is about to be freed.
    Invalidate the symbol as further actions on the symbol would result
    in bad data.  All access to s_smob->symbol should be gated by
-   syscm_get_valid_symbol_smob_arg which will raise an exception on invalid
-   symbols.  */
+   syscm_get_valid_symbol_smob_arg_unsafe which will raise an exception on
+   invalid symbols.  */
 
 static void
 syscm_del_objfile_symbols (struct objfile *objfile, void *datum)
 {
-  symbol_smob *s_smob = datum;
+  htab_t htab = datum;
 
-  while (s_smob != NULL)
+  if (htab != NULL)
     {
-      symbol_smob *next = (symbol_smob *) s_smob->base.next;
-
-      s_smob->symbol = NULL;
-      s_smob->base.next = NULL;
-      s_smob->base.prev = NULL;
-
-      s_smob = next;
+      htab_traverse_noresize (htab, syscm_mark_symbol_invalid, NULL);
+      htab_delete (htab);
     }
 }
 \f
diff --git a/gdb/testsuite/gdb.guile/scm-symbol.exp b/gdb/testsuite/gdb.guile/scm-symbol.exp
index 44e22f1..50f0181 100644
--- a/gdb/testsuite/gdb.guile/scm-symbol.exp
+++ b/gdb/testsuite/gdb.guile/scm-symbol.exp
@@ -59,6 +59,12 @@ if ![gdb_guile_runto_main] {
     return
 }
 
+# Test symbol eq? and equal?.
+gdb_test "guile (print (eq? (lookup-global-symbol \"main\") (lookup-global-symbol \"main\")))" \
+    "= #t"
+gdb_test "guile (print (equal? (lookup-global-symbol \"main\") (lookup-global-symbol \"main\")))" \
+    "= #t"
+
 gdb_breakpoint [gdb_get_line_number "Block break here."]
 gdb_continue_to_breakpoint "Block break here."
 gdb_scm_test_silent_cmd "guile (define frame (selected-frame))" \

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: guile scripting for gdb
  2013-11-11  6:28       ` Doug Evans
  2013-11-11  6:37         ` Doug Evans
@ 2013-11-11 11:55         ` Ludovic Courtès
  1 sibling, 0 replies; 9+ messages in thread
From: Ludovic Courtès @ 2013-11-11 11:55 UTC (permalink / raw)
  To: Doug Evans; +Cc: Doug Evans, guile-user, gdb-patches

Doug Evans <xdje42@gmail.com> skribis:

> On Sun, Nov 10, 2013 at 4:19 PM, Ludovic Courtès <ludo@gnu.org> wrote:
>> Doug Evans <dje@sebabeach.org> skribis:
>>
>>> On Thu, Nov 7, 2013 at 3:39 PM, Ludovic Courtès <ludo@gnu.org> wrote:
>>
>> [...]
>>
>>>> As discussed on IRC, one possible issue is eq?-ness of SMOBs: one would
>>>> usually expects pointer equality to be preserved at the Scheme level.
>>>
>>> Yeah.
>>> That'll require gdb maintaining its own table(s) for each kind of smob
>>> we want to intern.
>>> Definitely doable, though there are some issues.
>>> E.g., while std::vector<int> may be the same type in two different programs,
>>
>> What I had in mind was something simpler: suppose you have the very same
>> C struct pointer reaches the Scheme level, at two different points in
>> time, or via two different paths; currently gdb may end up allocating
>> two different SMOBs (i.e., two SMOBs that are not eq?), whereas I would
>> suggest making sure there’s only one SMOB.
>>
>> Example:
>>
>> --8<---------------cut here---------------start------------->8---
>> (gdb) guile (lookup-type "int")
>> #<gdb:type int>
>> (gdb) guile (arch-int-type (current-arch))
>> #<gdb:type int>
>> (gdb) guile (eq? (lookup-type "int") (arch-int-type (current-arch)))
>> #f
>> --8<---------------cut here---------------end--------------->8---
>>
>> Here I bet the underlying ‘struct type’ pointer return by ‘lookup-type’
>> is the same as that returned by ‘arch-int-type’, yet the SMOBs are
>> different.
>>
>> Fixing it would require maintaining a C->SMOB mapping.
>
> I'm pretty sure we have a sufficiently similar idea in mind.
> I mention the use of multiple tables because the lifetimes of
> different kinds of objects are different, and it may be easier to
> delete the table than iterate over each element looking for entries
> that need to be deleted.
>
> For reference sake, gdb doesn't guarantee that in the above example
> the underlying pointers are equal.
> While the arch provides a definition of "int" it can also come from
> the debug info in the program (actually there can and typically will
> be several copies, one from each .o in the program).
> eq-ness will be problematic even with the C->SMOB mapping.

Ah, OK.  Indeed, eq?-ness only would only matter in cases where gdb
guarantees pointer equality in the first place.

Thanks for the explanation,
Ludo’.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: guile scripting for gdb
  2013-11-11  6:37         ` Doug Evans
@ 2013-11-11 13:16           ` Ludovic Courtès
  0 siblings, 0 replies; 9+ messages in thread
From: Ludovic Courtès @ 2013-11-11 13:16 UTC (permalink / raw)
  To: Doug Evans; +Cc: guile-user, gdb-patches

Doug Evans <xdje42@gmail.com> skribis:

> Doug Evans <xdje42@gmail.com> writes:
>> On Sun, Nov 10, 2013 at 4:19 PM, Ludovic Courtès <ludo@gnu.org> wrote:
>>> Doug Evans <dje@sebabeach.org> skribis:
>>>> On Thu, Nov 7, 2013 at 3:39 PM, Ludovic Courtès <ludo@gnu.org> wrote:
>>>>> As discussed on IRC, one possible issue is eq?-ness of SMOBs: one would
>>>>> usually expects pointer equality to be preserved at the Scheme level.
>
> I uploaded to my github repo a branch with a prototype of implementing
> this for gdb symbols.
>
> https://github.com/dje42/gdb.git
> branch: eq-smobs

Excellent.

Ludo’.

PS: It may be possible to do away with mark/free procedures if targeting 2.0
    and later:
    <http://git.savannah.gnu.org/gitweb/?p=guile.git;a=commitdiff;h=aaa9ef33d8ace7c3060fa05c9a8bc64434616476>.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2013-11-11 11:55 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-04 16:04 guile scripting for gdb Doug Evans
     [not found] ` <87ob5vlr2s.fsf@gnu.org>
2013-11-09 19:47   ` Doug Evans
2013-11-09 19:48     ` Thien-Thi Nguyen
2013-11-10  6:26     ` Doug Evans
2013-11-11  1:50     ` Ludovic Courtès
2013-11-11  6:28       ` Doug Evans
2013-11-11  6:37         ` Doug Evans
2013-11-11 13:16           ` Ludovic Courtès
2013-11-11 11:55         ` Ludovic Courtès

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).