Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* Symbols/blocks questions
@ 2009-09-19 11:52 Vladimir Prus
  2009-09-19 14:34 ` Matt Rice
  2009-09-19 16:34 ` Joel Brobecker
  0 siblings, 2 replies; 9+ messages in thread
From: Vladimir Prus @ 2009-09-19 11:52 UTC (permalink / raw)
  To: gdb


I am trying to port some MI improvement from the Apple GDB,
and got some questions about symbol/block handling. I'd 
appreciate if somebody comment on it.

1. Given 'struct block *b', is it true that

    block_for_pc (b.startaddr) == b

?

2. Uness I am mistaken, in case of lines inside templates,
inline functions, and constructors, decode_line_1 returns 
just one sal. (And breakpoint.c explicitly expands thsoe in
expand_line_sal). In what cases will decode_line_1 actually
return multiple sals? For overloaded functions? Anything else?
Would it be sensible, eventually, to make decode_line_1
return all locations corresponding to file:line?

3. The code below, from Apple GDB, first calls decode_line_1
and then checks, for each sal, if the line passed to decode_line_1
is less then sal.line. How could this happen at all? I though that
if I ask decode_line_1 for line 10, then either it returns sals
for line 10, or it returns no sal at all.

(For context, the purpose of the code is, given file:line, to find
block in which variables should be looked up and evaluated, for -var-create)

Thanks,
Volodya

              TRY_CATCH (except, RETURN_MASK_ALL)
                {
                  /* The variable 's' will be advanced by decode_line_1.  */
                  char *s = block_addr; 
                  sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, NULL, 
                                        NULL);
                }

              if (except.reason >= 0 && sals.nelts >= 1)
                {
                  old_chain = make_cleanup (xfree, sals.sals);
                  
                  /* Default to global scope unless we find a better match.  */
                  var_type = NO_FRAME_NEEDED;
                  block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (sals.sals[0].symtab), 
                                                 GLOBAL_BLOCK);

                  unsigned long line = 0;
                  char *line_number_str = colon + 1;
                  if (strlen (line_number_str) > 0)
                      line = strtoul (line_number_str, NULL, 0);
                
                  /* Get the currently selected frame for reference.  */
                  struct frame_info *selected_frame = get_selected_frame (NULL);
                  if (selected_frame)
                    {
                      unsigned i;
                      struct symbol *func_sym;
                      func_sym = get_frame_function (selected_frame);
                      if (func_sym)
                        /* Iterate through all symtab_and_line structures 
                           returned and find the one that has the same  
                           function symbol as our frame.  */
                        for (i = 0; i < sals.nelts; i++)
                          {
                            struct symbol *sal_sym = 
                              find_pc_sect_function (sals.sals[i].pc, 
                                                     sals.sals[i].section);

                            if (func_sym == sal_sym)
                              {
                                /* If the requested line is less than the line
                                   found in the matching symtab_and_line 
                                   struct then we must use a global or static 
                                   as the scope since it doesn't fall within  
                                   the symtab_and_line struct that was 
                                   returned.  */
                                if (line && line < sal_sym->line)
                                  {
                                    /* Use a global scope.  */
                                    var_type = NO_FRAME_NEEDED;
                                    block = BLOCKVECTOR_BLOCK 
                                              (BLOCKVECTOR (sals.sals[i].symtab), 
                                               GLOBAL_BLOCK);
                                  }
                                else
                                  {
                                    /* We got a valid block match.  */
                                    var_type = USE_BLOCK_IN_FRAME;
                                    block = block_for_pc (sals.sals[i].pc);
                                    break;
                                  }
                              }
                          }
                    }               
                }


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

* Re: Symbols/blocks questions
  2009-09-19 11:52 Symbols/blocks questions Vladimir Prus
@ 2009-09-19 14:34 ` Matt Rice
  2009-09-19 16:34 ` Joel Brobecker
  1 sibling, 0 replies; 9+ messages in thread
From: Matt Rice @ 2009-09-19 14:34 UTC (permalink / raw)
  To: Vladimir Prus; +Cc: gdb

On Sat, Sep 19, 2009 at 4:52 AM, Vladimir Prus <ghost@cs.msu.su> wrote:
>
> I am trying to port some MI improvement from the Apple GDB,
> and got some questions about symbol/block handling. I'd
> appreciate if somebody comment on it.
>
> 1. Given 'struct block *b', is it true that
>
>    block_for_pc (b.startaddr) == b
>
> ?
>
> 2. Uness I am mistaken, in case of lines inside templates,
> inline functions, and constructors, decode_line_1 returns
> just one sal. (And breakpoint.c explicitly expands thsoe in
> expand_line_sal). In what cases will decode_line_1 actually
> return multiple sals? For overloaded functions? Anything else?
> Would it be sensible, eventually, to make decode_line_1
> return all locations corresponding to file:line?

decode_all_digits: single (break {,+,-}[0-9]+)
decode_objc: multiple via decode_line_2
decode_indirect: single  (break *functionptr)
decode_dollar: single (the first break $convenience or break $function found)
decode_compound: multiple via decode_line_2
decode_variable: single,  this one i'm less clear on

if passed a symbol which is not a function, it throws an error
'whatever' not found. through symbols which are functions e.g.
break main fall through, and those do not pass an error but return a
single value.

some of these could potentially return a single when ambiguity exist
based on whatever they decide.

e.g. a function
void $foobar() { }
void uhh() {}
set $foobar = &uhh
or something crazy like that that will never happen and could easily
be avoided by the user.

and decode_indirect i would assume uses whatever is in the scope
objc categories are technically not overloaded functions but I think
this is just semantics on the choice of the term overloaded function.

I wouldn't take this as gospel or anything, i could have easily
overlooked something, for instance i have no idea how
Ada hooks into this.


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

* Re: Symbols/blocks questions
  2009-09-19 11:52 Symbols/blocks questions Vladimir Prus
  2009-09-19 14:34 ` Matt Rice
@ 2009-09-19 16:34 ` Joel Brobecker
  2009-09-19 16:41   ` Vladimir Prus
  2009-09-22  9:47   ` Jerome Guitton
  1 sibling, 2 replies; 9+ messages in thread
From: Joel Brobecker @ 2009-09-19 16:34 UTC (permalink / raw)
  To: Vladimir Prus; +Cc: gdb

> 1. Given 'struct block *b', is it true that
> 
>     block_for_pc (b.startaddr) == b

My guess is that this is NOT true. Two blocks could have the same
start address if one block is nested inside the other...

> 2. Uness I am mistaken, in case of lines inside templates,
> inline functions, and constructors, decode_line_1 returns 
> just one sal. (And breakpoint.c explicitly expands thsoe in
> expand_line_sal). In what cases will decode_line_1 actually
> return multiple sals? For overloaded functions? Anything else?
> Would it be sensible, eventually, to make decode_line_1
> return all locations corresponding to file:line?
> 
> 3. The code below, from Apple GDB, first calls decode_line_1
> and then checks, for each sal, if the line passed to decode_line_1
> is less then sal.line. How could this happen at all? I though that
> if I ask decode_line_1 for line 10, then either it returns sals
> for line 10, or it returns no sal at all.

Jerome Guitton had a serious look at how things are done when
decoding breakpoint locations, mostly because we wanted Ada and C++
to use the same code for multiple-location breakpoints. I'll ask him
to see there is any useful piece of information that might help answer
these questions.

-- 
Joel


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

* Re: Symbols/blocks questions
  2009-09-19 16:34 ` Joel Brobecker
@ 2009-09-19 16:41   ` Vladimir Prus
  2009-09-19 17:02     ` Joel Brobecker
  2009-09-22  9:47   ` Jerome Guitton
  1 sibling, 1 reply; 9+ messages in thread
From: Vladimir Prus @ 2009-09-19 16:41 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb

On Saturday 19 September 2009 Joel Brobecker wrote:

> > 1. Given 'struct block *b', is it true that
> > 
> >     block_for_pc (b.startaddr) == b
> 
> My guess is that this is NOT true. Two blocks could have the same
> start address if one block is nested inside the other...

Then, it's probably likewise not true for any other random address
in block. And then, the only reliable way to identify a block is via
its address.

What I'm trying to do is make -stack-list-variables output block
together with a name of variable, and make -var-create accept
some block specification. This, together, should all to display
shadowed variables in frontend. Looks like 'block' should be
the string rendition of the address of struct block :-/

- Volodya


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

* Re: Symbols/blocks questions
  2009-09-19 16:41   ` Vladimir Prus
@ 2009-09-19 17:02     ` Joel Brobecker
  2009-09-19 18:35       ` Vladimir Prus
  0 siblings, 1 reply; 9+ messages in thread
From: Joel Brobecker @ 2009-09-19 17:02 UTC (permalink / raw)
  To: Vladimir Prus; +Cc: gdb

> Then, it's probably likewise not true for any other random address
> in block. And then, the only reliable way to identify a block is via
> its address.

I think that's correct. We have routines IIRC that locate the innermost
block for a PC, or something like that, but I don't think we identify
blocks by their start address...

> What I'm trying to do is make -stack-list-variables output block
> together with a name of variable, and make -var-create accept
> some block specification. This, together, should all to display
                                                   ^^^allow ?
> shadowed variables in frontend. Looks like 'block' should be
> the string rendition of the address of struct block :-/

Depending on the language, lexical blocks can be named, and it looks
like DWARF supports that, so I suppose you could you that.  But blocks
can definitely be annonymous too, in which case the "string rendition"
might be a challenge...

-- 
Joel


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

* Re: Symbols/blocks questions
  2009-09-19 17:02     ` Joel Brobecker
@ 2009-09-19 18:35       ` Vladimir Prus
  2009-09-20 15:52         ` Joel Brobecker
  0 siblings, 1 reply; 9+ messages in thread
From: Vladimir Prus @ 2009-09-19 18:35 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb

On Saturday 19 September 2009 Joel Brobecker wrote:

> > Then, it's probably likewise not true for any other random address
> > in block. And then, the only reliable way to identify a block is via
> > its address.
> 
> I think that's correct. We have routines IIRC that locate the innermost
> block for a PC, or something like that, but I don't think we identify
> blocks by their start address...
> 
> > What I'm trying to do is make -stack-list-variables output block
> > together with a name of variable, and make -var-create accept
> > some block specification. This, together, should all to display
>                                                    ^^^allow ?
> > shadowed variables in frontend. Looks like 'block' should be
> > the string rendition of the address of struct block :-/
> 
> Depending on the language, lexical blocks can be named, and it looks
> like DWARF supports that, so I suppose you could you that.  But blocks
> can definitely be annonymous too, in which case the "string rendition"
> might be a challenge...

Well, string rendition is not really a challenge. You take 
struct block *, and then use phex :-) The id need not be
stable across debug sessions, it just should be stable within
one debug session. 

- Volodya


> 
> 


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

* Re: Symbols/blocks questions
  2009-09-19 18:35       ` Vladimir Prus
@ 2009-09-20 15:52         ` Joel Brobecker
  2009-09-20 20:30           ` Daniel Jacobowitz
  0 siblings, 1 reply; 9+ messages in thread
From: Joel Brobecker @ 2009-09-20 15:52 UTC (permalink / raw)
  To: Vladimir Prus; +Cc: gdb

> Well, string rendition is not really a challenge. You take 
> struct block *, and then use phex :-) The id need not be
> stable across debug sessions, it just should be stable within
> one debug session. 

OK - I just thought that you wanted the user to be able to identify
these blocks from the source code. The same way we do when doing

    (gdb) print FUNC::VAR

If you think people will be happy with an arbitrary block ID, then
indeed, that's easy (it's actually how task IDs are identified in
VxWorks, it's the address of the TCB).

-- 
Joel


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

* Re: Symbols/blocks questions
  2009-09-20 15:52         ` Joel Brobecker
@ 2009-09-20 20:30           ` Daniel Jacobowitz
  0 siblings, 0 replies; 9+ messages in thread
From: Daniel Jacobowitz @ 2009-09-20 20:30 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: Vladimir Prus, gdb

On Sun, Sep 20, 2009 at 08:51:54AM -0700, Joel Brobecker wrote:
> > Well, string rendition is not really a challenge. You take 
> > struct block *, and then use phex :-) The id need not be
> > stable across debug sessions, it just should be stable within
> > one debug session. 
> 
> OK - I just thought that you wanted the user to be able to identify
> these blocks from the source code. The same way we do when doing
> 
>     (gdb) print FUNC::VAR
> 
> If you think people will be happy with an arbitrary block ID, then
> indeed, that's easy (it's actually how task IDs are identified in
> VxWorks, it's the address of the TCB).

FWIW, I think we should avoid using internal pointers in the MI
interface.  Not only does it open up a can of worms (should we really
be dereferencing user-supplied pointers?  how long are their
lifetimes?), but it's going to make it hard to reproduce bugs given an
MI session transcript.

The inline function support has a way of representing blocks as
tuples.  That might help.  The tuples are start address and "depth";
the depth number would be different here, but serves the same
purpose.

-- 
Daniel Jacobowitz
CodeSourcery


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

* Re: Symbols/blocks questions
  2009-09-19 16:34 ` Joel Brobecker
  2009-09-19 16:41   ` Vladimir Prus
@ 2009-09-22  9:47   ` Jerome Guitton
  1 sibling, 0 replies; 9+ messages in thread
From: Jerome Guitton @ 2009-09-22  9:47 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: Vladimir Prus, gdb

Joel Brobecker (brobecker@adacore.com):

> Jerome Guitton had a serious look at how things are done when
> decoding breakpoint locations, mostly because we wanted Ada and C++
> to use the same code for multiple-location breakpoints. I'll ask him
> to see there is any useful piece of information that might help answer
> these questions.

Not much to add to what Matt already said; and my knowledge in this
area have seriously decreased. I will tell you what I *think* I know.

IIRC, if decode_line_1 returned more than one line, multiple
breakpoints would be created (not a multiple-location
breakpoint). Precisely what happens for overloaded functions: multiple
breakpoints are created. See test ovldbreak.exp.

IIUC, multiple-location breakpoints are only used when the same
"location expression" (addr_string) has to be used to identify a set of
breakpoints; so that, at breakpoint re-set, the same addr_string can
be used to re-create the whole set of sub-breakpoints.

So, I *assume* that if decode_line_1 returns more than one location,
each of these locations has to refer to a different source location;
they should not have the same addr_string. If the same addr_string was
used for such breakpoints, the breakpoint reset would call
decode_line_1 for each of them, find several instances for each of
them, and create duplicates.

Let me give an example from my experience of the problem. In AdaCore's
debugger, we have a feature that allows the user to select a few
choices from the list of all locations that corresponds to a FILE:LINE
expression. Say, if the user set a breakpoint in a generic, the
debugger asks him on which instances breakpoints should be created,
and this user can select several choices in the list. Now, to avoid
having the re-set problem, the debugger has to rewrite the addr_string
to a sort of "canonical" location. If multiple locations are found for
FILE:LINE, say, in Func1 and Func2, then two breakpoints are set in
Func1:FILE:LINE and Func2:FILE:LINE. That's the kind of things that
you have to do when decode_line_1 returns more than 1 location...


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

end of thread, other threads:[~2009-09-22  9:47 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-19 11:52 Symbols/blocks questions Vladimir Prus
2009-09-19 14:34 ` Matt Rice
2009-09-19 16:34 ` Joel Brobecker
2009-09-19 16:41   ` Vladimir Prus
2009-09-19 17:02     ` Joel Brobecker
2009-09-19 18:35       ` Vladimir Prus
2009-09-20 15:52         ` Joel Brobecker
2009-09-20 20:30           ` Daniel Jacobowitz
2009-09-22  9:47   ` Jerome Guitton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox