* gdb 6.3 C++ breakpoint in constructor/destructor patch
@ 2005-05-01 18:33 Thomas Maier
2005-05-01 19:05 ` Daniel Jacobowitz
0 siblings, 1 reply; 5+ messages in thread
From: Thomas Maier @ 2005-05-01 18:33 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1752 bytes --]
Hello,
I want to supply a patch for the released gdb 6.3, that fixes partially
the gdb bugs
gdb/1091: Constructor breakpoints ignored
gdb/1193: g++ 3.3 creates multiple constructors: gdb 5.3 can't set
breakpoints
I was really confused, why my programs to not stop at the breakpoint in
constructor/destructors. Now i know, it is not the fault of my programs ;)
Since this anoying problem seems to be in gdb since the gcc 3.x release, i
guess, no one else a) has this problem (i don't believe so) or b) will not
fix it. So i did it ;)
This modification is only made for commands like "break
[source]:<lineno>". For C++ constructors and destructors, the patch
creates more than one breakpoint at the source at lineno, but each
generated breakpoint will have another address!
NOTE: this is only a simple "hack". I have spent only one day to get into
gdb source code and do the modification.
It would be better, to create only one breakpoint in such C++ constructors
and destructors and assign multiple addresses to it. But this needs a huge
modification of gdb, i guess ;)
ChangeLog:
2005-04-30 Thomas Maier <balagi@justmail.de>
* breakpoint.c linespec.c symtab.c symtab.h
Add better support for breakpoints in C++ constructors
and destructors.
NOTE: this is only a simple hack.
This modification is only made for commands like
"break [source]:<lineno>". It creates more than one
breakpoint at the source at lineno, but each
generated breakpoint will have another address!
For more information see also
http://people.freenet.de/BalaGi
I hope this patch is helpful, maybe some of you can do it into gdb or even
use it as a base for a better patch fixing 1091 and 1193 ;)
Greetings
Thomas Maier
[-- Attachment #2: patch-gdb-6.3-c++-bpconstr --]
[-- Type: application/octet-stream, Size: 10716 bytes --]
diff -Nur gdb-6.3/gdb/ChangeLog gdb-6.3.1/gdb/ChangeLog
--- gdb-6.3/gdb/ChangeLog 2004-11-08 17:21:20.000000000 +0100
+++ gdb-6.3.1/gdb/ChangeLog 2005-04-30 22:03:12.382049280 +0200
@@ -1,3 +1,33 @@
+2005-04-30 Thomas Maier <balagi@justmail.de>
+
+ * breakpoint.c linespec.c symtab.c symtab.h
+ Add better support for breakpoints in C++ constructors
+ and destructors.
+ NOTE: this is only a simple hack.
+ This modification is only made for commands like
+ "break [source]:<lineno>". It creates more than one
+ breakpoint at the source at lineno, but each
+ generated breakpoint will have another address!
+
+ See also: (taken from PROBLEMS file)
+ gdb/1091: Constructor breakpoints ignored
+ gdb/1193: g++ 3.3 creates multiple constructors: gdb 5.3 can't set breakpoints
+
+ When gcc 3.x compiles a C++ constructor or C++ destructor, it generates
+ 2 or 3 different versions of the object code. These versions have
+ unique mangled names (they have to, in order for linking to work), but
+ they have identical source code names, which leads to a great deal of
+ confusion. Specifically, if you set a breakpoint in a constructor or a
+ destructor, gdb will put a breakpoint in one of the versions, but your
+ program may execute the other version. This makes it impossible to set
+ breakpoints reliably in constructors or destructors.
+
+ gcc 3.x generates these multiple object code functions in order to
+ implement virtual base classes. gcc 2.x generated just one object code
+ function with a hidden parameter, but gcc 3.x conforms to a multi-vendor
+ ABI for C++ which requires multiple object code functions.
+
+
2004-11-08 Andrew Cagney <cagney@gnu.org>
GDB 6.3 released.
diff -Nur gdb-6.3/gdb/breakpoint.c gdb-6.3.1/gdb/breakpoint.c
--- gdb-6.3/gdb/breakpoint.c 2004-10-08 19:30:46.000000000 +0200
+++ gdb-6.3.1/gdb/breakpoint.c 2005-04-30 20:58:10.000000000 +0200
@@ -5309,10 +5309,26 @@
mention (b);
}
- if (sals.nelts > 1)
+ /* balagi 04/30/2005 only warn it this is not a multipc */
+ if (sals.nelts > 1 )
{
- warning ("Multiple breakpoints were set.");
- warning ("Use the \"delete\" command to delete unwanted breakpoints.");
+ if ( sals.sals[0].multipc )
+ {
+ if ( sals.sals[0].symtab->language == language_cplus )
+ {
+ warning("Multiple breakpoints were set, maybe in a C++ de/constructor.");
+ }
+ else
+ {
+ warning ("Multiple breakpoints were set at the same line,");
+ warning ("but at different addresses!");
+ }
+ }
+ else
+ {
+ warning ("Multiple breakpoints were set.");
+ warning ("Use the \"delete\" command to delete unwanted breakpoints.");
+ }
}
/* That's it. Discard the cleanups for data inserted into the
breakpoint. */
@@ -7206,6 +7222,37 @@
s = b->addr_string;
sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL,
not_found_ptr);
+ /* balagi 04/30/2005
+ if sal->multipc is not 0, the sals was returned from
+ decode_all_digits() and marks that the same source
+ line have multiple pc's (e.g. GNU g++ >3.x constructors).
+ In this case, find the sal that matches this breakpoint
+ and check only this sal against other breakpoints.
+ NOTE: is sal->multipc not 0, then sal->pc is
+ already resolved!
+ */
+ if ( sals.nelts > 1 && sals.sals[0].multipc )
+ {
+ for ( i = 0; i < sals.nelts; i++ )
+ {
+ if ( b->loc->address == sals.sals[i].pc )
+ break;
+ }
+ if ( i == sals.nelts ) /* ups, not found */
+ {
+ /* TODO: what should we do here???
+ if we do nothing, gdb generates
+ several warnings etc....
+ */
+ }
+ else
+ {
+ /* modify sals to only represent the found sal */
+ sals.nelts = 1;
+ if ( i > 0 )
+ sals.sals[0] = sals.sals[i];
+ }
+ }
for (i = 0; i < sals.nelts; i++)
{
resolve_sal_pc (&sals.sals[i]);
diff -Nur gdb-6.3/gdb/linespec.c gdb-6.3.1/gdb/linespec.c
--- gdb-6.3/gdb/linespec.c 2004-06-18 23:36:15.000000000 +0200
+++ gdb-6.3.1/gdb/linespec.c 2005-04-30 19:19:40.000000000 +0200
@@ -90,7 +90,7 @@
struct symbol **sym_arr);
static void build_canonical_line_spec (struct symtab_and_line *,
- char *, char ***);
+ char *, char ***, int);
static char *find_toplevel_char (char *s, char c);
@@ -376,23 +376,27 @@
the SAL has a symtab.
If SYMNAME is non-NULL the canonical line spec is `filename:symname'.
If SYMNAME is NULL the line number from SAL is used and the canonical
- line spec is `filename:linenum'. */
+ line spec is `filename:linenum'.
+ balagi 04/30/2005 NUMDUPS duplicates the canonical name n times */
static void
build_canonical_line_spec (struct symtab_and_line *sal, char *symname,
- char ***canonical)
+ char ***canonical, int numdups)
{
char **canonical_arr;
char *canonical_name;
char *filename;
struct symtab *s = sal->symtab;
+ int i;
if (s == (struct symtab *) NULL
|| s->filename == (char *) NULL
|| canonical == (char ***) NULL)
return;
- canonical_arr = (char **) xmalloc (sizeof (char *));
+ if ( numdups < 1 )
+ numdups = 1;
+ canonical_arr = (char **) xmalloc (sizeof (char *) * numdups);
*canonical = canonical_arr;
filename = s->filename;
@@ -407,6 +411,11 @@
sprintf (canonical_name, "%s:%d", filename, sal->line);
}
canonical_arr[0] = canonical_name;
+ for ( i = 1; i < numdups; i++ )
+ {
+ canonical_arr[i] = xmalloc(strlen(canonical_name) + 2);
+ strcpy(canonical_arr[i], canonical_name);
+ }
}
@@ -1129,7 +1138,7 @@
{
/* Canonicalize this, so it remains resolved for dylib loads. */
values.sals[0] = find_function_start_sal (sym, funfirstline);
- build_canonical_line_spec (values.sals, SYMBOL_NATURAL_NAME (sym), canonical);
+ build_canonical_line_spec (values.sals, SYMBOL_NATURAL_NAME (sym), canonical, 1);
}
else
{
@@ -1561,8 +1570,7 @@
struct symtab *file_symtab, char *q)
{
- struct symtabs_and_lines values;
- struct symtab_and_line val;
+ int line;
enum sign
{
@@ -1573,8 +1581,6 @@
/* We might need a canonical line spec if no file was specified. */
int need_canonical = (file_symtab == 0) ? 1 : 0;
- init_sal (&val);
-
/* This is where we need to make sure that we have good defaults.
We must guarantee that this section of code is never executed
when we are called with just a function name, since
@@ -1592,22 +1598,22 @@
sign = plus, (*argptr)++;
else if (**argptr == '-')
sign = minus, (*argptr)++;
- val.line = atoi (*argptr);
+ line = atoi (*argptr);
switch (sign)
{
case plus:
if (q == *argptr)
- val.line = 5;
+ line = 5;
if (file_symtab == 0)
- val.line = default_line + val.line;
+ line = default_line + line;
break;
case minus:
if (q == *argptr)
- val.line = 15;
+ line = 15;
if (file_symtab == 0)
- val.line = default_line - val.line;
+ line = default_line - line;
else
- val.line = 1;
+ line = 1;
break;
case none:
break; /* No need to adjust val.line. */
@@ -1622,18 +1628,61 @@
/* It is possible that this source file has more than one symtab,
and that the new line number specification has moved us from the
default (in file_symtab) to a new one. */
- val.symtab = find_line_symtab (file_symtab, val.line, NULL, NULL);
- if (val.symtab == 0)
- val.symtab = file_symtab;
-
- val.pc = 0;
- values.sals = (struct symtab_and_line *)
- xmalloc (sizeof (struct symtab_and_line));
- values.sals[0] = val;
- values.nelts = 1;
- if (need_canonical)
- build_canonical_line_spec (values.sals, NULL, canonical);
- return values;
+ {
+ /* balagi 04/30/2005
+ in case language == language_cplus, we try to find other
+ entries in the linetable with the same line number
+ to be able to set breakpoints in C++ constructors/
+ destructors (for GNU C++ >3.x) */
+ const int maxlti = 128;
+ int ltindices[maxlti];
+ int num = 0;
+ int idx = -1;
+ struct symtabs_and_lines values;
+ struct linetable* lt;
+ struct symtab* st = find_line_symtab(file_symtab, line, &idx, NULL);
+ if ( st != NULL && idx >= 0 )
+ {
+ lt = LINETABLE(st);
+ ltindices[num++] = idx;
+ if ( st->language == language_cplus )
+ {
+ /* search for more entries */
+ for ( idx++; idx < lt->nitems; idx++ )
+ {
+ if ( lt->item[idx].line == line )
+ {
+ ltindices[num++] = idx;
+ if ( num >= maxlti )
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ st = file_symtab;
+ lt = LINETABLE(st);
+ ltindices[num++] = -1;
+ }
+
+ values.sals = (struct symtab_and_line*)
+ xmalloc(sizeof(struct symtab_and_line) * num);
+ values.nelts = num;
+ for ( idx = 0; idx < num; idx++ )
+ {
+ struct symtab_and_line* val = &values.sals[idx];
+ init_sal(val);
+ /* set the pc here if available ! */
+ val->pc = (ltindices[idx] >= 0 ? lt->item[ltindices[idx]].pc : 0);
+ val->line = line;
+ val->symtab = st;
+ val->multipc = (num > 1 ? 1 : 0);
+ }
+ if (need_canonical)
+ build_canonical_line_spec (&values.sals[0], NULL, canonical, num);
+ return values;
+ }
}
\f
@@ -1705,7 +1754,7 @@
values.nelts = 1;
if (need_canonical)
- build_canonical_line_spec (values.sals, NULL, canonical);
+ build_canonical_line_spec (values.sals, NULL, canonical, 1);
return values;
}
@@ -1798,7 +1847,7 @@
struct blockvector *bv = BLOCKVECTOR (sym_symtab);
struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
if (lookup_block_symbol (b, copy, NULL, VAR_DOMAIN) != NULL)
- build_canonical_line_spec (values.sals, copy, canonical);
+ build_canonical_line_spec (values.sals, copy, canonical, 1);
}
return values;
}
diff -Nur gdb-6.3/gdb/symtab.c gdb-6.3.1/gdb/symtab.c
--- gdb-6.3/gdb/symtab.c 2004-10-02 11:55:15.000000000 +0200
+++ gdb-6.3.1/gdb/symtab.c 2005-04-30 21:23:15.000000000 +0200
@@ -700,6 +700,7 @@
sal->line = 0;
sal->pc = 0;
sal->end = 0;
+ sal->multipc = 0; /* balagi 04/30/2005 */
}
\f
diff -Nur gdb-6.3/gdb/symtab.h gdb-6.3.1/gdb/symtab.h
--- gdb-6.3/gdb/symtab.h 2004-06-10 22:05:44.000000000 +0200
+++ gdb-6.3.1/gdb/symtab.h 2005-04-30 19:19:40.000000000 +0200
@@ -1198,6 +1198,11 @@
CORE_ADDR pc;
CORE_ADDR end;
+
+ /* balagi 04/30/2005
+ if not 0, it exists another symtab_and_line with the same
+ symtab and line, but a different pc */
+ int multipc;
};
extern void init_sal (struct symtab_and_line *sal);
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: gdb 6.3 C++ breakpoint in constructor/destructor patch
2005-05-01 18:33 gdb 6.3 C++ breakpoint in constructor/destructor patch Thomas Maier
@ 2005-05-01 19:05 ` Daniel Jacobowitz
2005-05-01 20:54 ` Thomas Maier
0 siblings, 1 reply; 5+ messages in thread
From: Daniel Jacobowitz @ 2005-05-01 19:05 UTC (permalink / raw)
To: Thomas Maier; +Cc: gdb-patches
On Sun, May 01, 2005 at 08:32:12PM +0200, Thomas Maier wrote:
> Hello,
>
> I want to supply a patch for the released gdb 6.3, that fixes partially
> the gdb bugs
>
> gdb/1091: Constructor breakpoints ignored
> gdb/1193: g++ 3.3 creates multiple constructors: gdb 5.3 can't set
> breakpoints
>
> I was really confused, why my programs to not stop at the breakpoint in
> constructor/destructors. Now i know, it is not the fault of my programs ;)
> Since this anoying problem seems to be in gdb since the gcc 3.x release, i
> guess, no one else a) has this problem (i don't believe so) or b) will not
> fix it. So i did it ;)
>
> This modification is only made for commands like "break
> [source]:<lineno>". For C++ constructors and destructors, the patch
> creates more than one breakpoint at the source at lineno, but each
> generated breakpoint will have another address!
>
> NOTE: this is only a simple "hack". I have spent only one day to get into
> gdb source code and do the modification.
> It would be better, to create only one breakpoint in such C++ constructors
> and destructors and assign multiple addresses to it. But this needs a huge
> modification of gdb, i guess ;)
This is not a very useful change, because it only handles the case
where everything at a particular line is in the same symtab. Often
this will not be the case.
If you take a look at the archives for the list, you will find a lot of
discussion on this subject - as well as a prototype patch I posted
earlier this year. That patch may be good enough for your needs, since
it handles the file:lineno case. But it isn't done yet, and I haven't
had time to go back to it yet.
--
Daniel Jacobowitz
CodeSourcery, LLC
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: gdb 6.3 C++ breakpoint in constructor/destructor patch
2005-05-01 19:05 ` Daniel Jacobowitz
@ 2005-05-01 20:54 ` Thomas Maier
2005-05-01 21:56 ` Daniel Jacobowitz
0 siblings, 1 reply; 5+ messages in thread
From: Thomas Maier @ 2005-05-01 20:54 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Hello,
On Sun, 1 May 2005 15:05:32 -0400, Daniel Jacobowitz <drow@false.org>
wrote:
> On Sun, May 01, 2005 at 08:32:12PM +0200, Thomas Maier wrote:
>> Hello,
>>
>> I want to supply a patch for the released gdb 6.3, that fixes partially
>> the gdb bugs
>>
>> gdb/1091: Constructor breakpoints ignored
>> gdb/1193: g++ 3.3 creates multiple constructors: gdb 5.3 can't set
>> breakpoints
>>
>> I was really confused, why my programs to not stop at the breakpoint in
>> constructor/destructors. Now i know, it is not the fault of my programs
>> ;)
>> Since this anoying problem seems to be in gdb since the gcc 3.x
>> release, i
>> guess, no one else a) has this problem (i don't believe so) or b) will
>> not
>> fix it. So i did it ;)
>>
>> This modification is only made for commands like "break
>> [source]:<lineno>". For C++ constructors and destructors, the patch
>> creates more than one breakpoint at the source at lineno, but each
>> generated breakpoint will have another address!
>>
>> NOTE: this is only a simple "hack". I have spent only one day to get
>> into
>> gdb source code and do the modification.
>> It would be better, to create only one breakpoint in such
>> C++ constructors
>> and destructors and assign multiple addresses to it. But this needs a
>> huge
>> modification of gdb, i guess ;)
>
> This is not a very useful change, because it only handles the case
> where everything at a particular line is in the same symtab. Often
> this will not be the case.
Ok, hmm, then the code in find_line_symtab() must not return one symtab,
which is used to find one or more references to the lineno, it must return
a list of symtabs with references to this lineno. Means, a similar search
over all symtabs which is already done in find_line_symtab().
Would that be enough to handle the file:lineno case?
(If yes it think a new function like find_multi_line_symtab() is the best
way to do it, then in decode_all_digits() fill in the sals with the found
symtabs + linenos)
> If you take a look at the archives for the list, you will find a lot of
> discussion on this subject - as well as a prototype patch I posted
> earlier this year. That patch may be good enough for your needs, since
> it handles the file:lineno case. But it isn't done yet, and I haven't
> had time to go back to it yet.
>
Intresting...
-Thomas Maier
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: gdb 6.3 C++ breakpoint in constructor/destructor patch
2005-05-01 20:54 ` Thomas Maier
@ 2005-05-01 21:56 ` Daniel Jacobowitz
2005-05-03 17:46 ` Thomas Maier
0 siblings, 1 reply; 5+ messages in thread
From: Daniel Jacobowitz @ 2005-05-01 21:56 UTC (permalink / raw)
To: Thomas Maier; +Cc: gdb-patches
On Sun, May 01, 2005 at 10:53:05PM +0200, Thomas Maier wrote:
> Ok, hmm, then the code in find_line_symtab() must not return one symtab,
> which is used to find one or more references to the lineno, it must return
> a list of symtabs with references to this lineno. Means, a similar search
> over all symtabs which is already done in find_line_symtab().
> Would that be enough to handle the file:lineno case?
>
> (If yes it think a new function like find_multi_line_symtab() is the best
> way to do it, then in decode_all_digits() fill in the sals with the found
> symtabs + linenos)
It's a representation problem. I found it much more effective to have
decode_line_1 only return one symtab_and_line structure, and then
expand them to multiple PCs later, regardless of whether the symtab
returned was the only relevant one. Otherwise, things like "list" will
get confused.
--
Daniel Jacobowitz
CodeSourcery, LLC
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: gdb 6.3 C++ breakpoint in constructor/destructor patch
2005-05-01 21:56 ` Daniel Jacobowitz
@ 2005-05-03 17:46 ` Thomas Maier
0 siblings, 0 replies; 5+ messages in thread
From: Thomas Maier @ 2005-05-03 17:46 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1696 bytes --]
Hello,
ok, second try...
This patch only modifies breakpoint.c
It "expands" the sals returned by decode_line_1().
Means all symtabs are searched for a linetable entries that match the
required
filename and lineno (returned by decode_line_1()) and then
new sal's are created, and this creates (in some cases, e.g.
C++ constructors of
gcc 4) more then one breakpoint
at the same line and file, but at different pc's.
The expand is done in a new function called breakpoint_sals_expand().
On a i686 platform with gcc 4.0 i had no problems with this modification
so far.
I think, it works good enough for me ;) At least till the gdb experts fix
this
problem themselfs ;)
-Thomas Maier
On Sun, 1 May 2005 17:56:08 -0400, Daniel Jacobowitz <drow@false.org>
wrote:
> On Sun, May 01, 2005 at 10:53:05PM +0200, Thomas Maier wrote:
>> Ok, hmm, then the code in find_line_symtab() must not return one symtab,
>> which is used to find one or more references to the lineno, it must
>> return
>> a list of symtabs with references to this lineno. Means, a similar
>> search
>> over all symtabs which is already done in find_line_symtab().
>> Would that be enough to handle the file:lineno case?
>>
>> (If yes it think a new function like find_multi_line_symtab() is the
>> best
>> way to do it, then in decode_all_digits() fill in the sals with the
>> found
>> symtabs + linenos)
>
> It's a representation problem. I found it much more effective to have
> decode_line_1 only return one symtab_and_line structure, and then
> expand them to multiple PCs later, regardless of whether the symtab
> returned was the only relevant one. Otherwise, things like "list" will
> get confused.
>
[-- Attachment #2: patch-gdb-6.3-c++-bpconstr --]
[-- Type: application/octet-stream, Size: 7023 bytes --]
diff -cpNr gdb-6.3/gdb/ChangeLog gdb-6.3.1/gdb/ChangeLog
*** gdb-6.3/gdb/ChangeLog Mon Nov 8 17:21:20 2004
--- gdb-6.3.1/gdb/ChangeLog Tue May 3 17:11:53 2005
***************
*** 1,3 ****
--- 1,32 ----
+ 2005-04-30 Thomas Maier <balagi@justmail.de>
+
+ * breakpoint.c
+ Add better support for breakpoints in C++ constructors
+ and destructors.
+ NOTE: this is only a simple hack.
+ It creates more than one
+ breakpoint at the source at lineno, but each
+ generated breakpoint will have another address!
+
+ See also: (taken from PROBLEMS file)
+ gdb/1091: Constructor breakpoints ignored
+ gdb/1193: g++ 3.3 creates multiple constructors: gdb 5.3 can't set breakpoints
+
+ When gcc 3.x compiles a C++ constructor or C++ destructor, it generates
+ 2 or 3 different versions of the object code. These versions have
+ unique mangled names (they have to, in order for linking to work), but
+ they have identical source code names, which leads to a great deal of
+ confusion. Specifically, if you set a breakpoint in a constructor or a
+ destructor, gdb will put a breakpoint in one of the versions, but your
+ program may execute the other version. This makes it impossible to set
+ breakpoints reliably in constructors or destructors.
+
+ gcc 3.x generates these multiple object code functions in order to
+ implement virtual base classes. gcc 2.x generated just one object code
+ function with a hidden parameter, but gcc 3.x conforms to a multi-vendor
+ ABI for C++ which requires multiple object code functions.
+
+
2004-11-08 Andrew Cagney <cagney@gnu.org>
GDB 6.3 released.
diff -cpNr gdb-6.3/gdb/breakpoint.c gdb-6.3.1/gdb/breakpoint.c
*** gdb-6.3/gdb/breakpoint.c Fri Oct 8 19:30:46 2004
--- gdb-6.3.1/gdb/breakpoint.c Tue May 3 17:16:07 2005
*************** do_captured_parse_breakpoint (struct ui_
*** 5098,5103 ****
--- 5098,5205 ----
return GDB_RC_OK;
}
+ /* balagi 05/02/2005
+ Try to find other entries in all available symtabs that match
+ filename and line number.
+ This is done only if language == C++ !!!
+
+ NOTE: sal.pc will be set here if language == C++
+
+ *SALS is replaced by a new allocated structure, the previous
+ content is released. Dito *ADDR_STRING .
+ */
+ static void
+ breakpoint_sals_expand (struct symtabs_and_lines* sals, char*** addr_string)
+ {
+ /* assume max 128 other entries, should be enough ;) */
+ int maxsal = sals->nelts + 128;
+ int i;
+ struct symtabs_and_lines xsals;
+ xsals.sals = (struct symtab_and_line*)
+ xmalloc(sizeof(struct symtab_and_line*) * maxsal);
+ xsals.nelts = 0;
+
+ /* need to rebuild the addr_string's, if requested ! */
+ char** xaddr_string = NULL;
+ if ( addr_string && *addr_string )
+ xaddr_string = (char**)xmalloc(sizeof(char*) * maxsal);
+
+ /* for each sal */
+ for ( i = 0; i < sals->nelts; i++ )
+ {
+ struct symtab_and_line* sal = &(sals->sals[i]);
+ struct objfile* objfile;
+ struct symtab* st;
+
+ if ( sal->symtab->language != language_cplus )
+ {
+ /* not C++, simply copy the sal into xsals */
+ if ( xsals.nelts < maxsal )
+ {
+ if ( xaddr_string )
+ xaddr_string[xsals.nelts] = ((*addr_string)[i]
+ ? xstrdup((*addr_string)[i]) : NULL);
+ xsals.sals[xsals.nelts++] = *sal;
+ }
+ continue;
+ }
+
+ /* search all symtabs to find a match for other entries */
+ ALL_SYMTABS(objfile, st)
+ {
+ struct linetable* l;
+ int k;
+ if (strcmp(sal->symtab->filename, st->filename) != 0)
+ continue;
+ l = LINETABLE(st);
+ for ( k = 0; k < l->nitems; k++ )
+ {
+ int j;
+
+ if ( l->item[k].line != sal->line )
+ continue;
+
+ /* avoid duplicates. only match pc, should be
+ good enough.
+ */
+ for (j = 0; j < xsals.nelts; j++)
+ {
+ if ( xsals.sals[j].pc != 0
+ && xsals.sals[j].pc == l->item[k].pc )
+ break;
+ }
+ if ( j < xsals.nelts )
+ continue;
+
+ if ( xsals.nelts >= maxsal )
+ continue;
+ if ( xaddr_string )
+ xaddr_string[xsals.nelts] = ((*addr_string)[i]
+ ? xstrdup((*addr_string)[i]) : NULL);
+ struct symtab_and_line* sl = &(xsals.sals[xsals.nelts++]);
+ init_sal(sl);
+ sl->symtab = st;
+ sl->line = sal->line;
+ sl->pc = l->item[k].pc; /* set pc !! */
+ }
+ }
+ }
+
+ /* ok, cleanup old structures and copy over new ones */
+ if ( addr_string && *addr_string != NULL )
+ {
+ for ( i = 0; i < sals->nelts; i++ )
+ {
+ if ( (*addr_string)[i] != NULL )
+ xfree((*addr_string)[i]);
+ }
+ xfree(*addr_string);
+ *addr_string = xaddr_string;
+ }
+ xfree(sals->sals);
+ *sals = xsals;
+ }
+
/* Set a breakpoint according to ARG (function, linenum or *address)
flag: first bit : 0 non-temporary, 1 temporary.
second bit : 0 normal breakpoint, 1 hardware breakpoint.
*************** break_command_1 (char *arg, int flag, in
*** 5189,5194 ****
--- 5291,5299 ----
if (!pending)
{
+ /* balagi 05/02/2005 expand (C++) breakpoints... */
+ breakpoint_sals_expand(&sals, &addr_string);
+
/* Make sure that all storage allocated to SALS gets freed. */
make_cleanup (xfree, sals.sals);
*************** do_captured_breakpoint (void *data)
*** 5364,5369 ****
--- 5469,5477 ----
/* Create a chain of things at always need to be cleaned up. */
old_chain = make_cleanup (null_cleanup, 0);
+
+ /* balagi 05/02/2005 expand (C++) breakpoints... */
+ breakpoint_sals_expand(&sals, &addr_string);
/* Always have a addr_string array, even if it is empty. */
make_cleanup (xfree, addr_string);
*************** breakpoint_re_set_one (void *bint)
*** 7206,7211 ****
--- 7314,7350 ----
s = b->addr_string;
sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL,
not_found_ptr);
+
+ /* balagi 05/02/2005
+ This is really a bad hack. If there are more then one sal
+ expanded by breakpoint_sals_expand(),
+ we must find the matching sal to the given breakpoint.
+ We only can use pc here, can't we?!
+ What if no matching pc to b->loc->address is found??
+ Hmm, don't know....
+ */
+ breakpoint_sals_expand(&sals, NULL);
+ for (i = 0; i < sals.nelts; i++)
+ {
+ /* only for C++ !! */
+ if ( sals.sals[i].symtab->language != language_cplus )
+ continue;
+ if ( sals.sals[i].pc == b->loc->address )
+ {
+ sals.nelts = 1;
+ if ( i > 0 )
+ sals.sals[0] = sals.sals[i];
+ break;
+ }
+ }
+
+ /* balagi 05/02/2005
+ Question: is it a good idea, to allow to have multiple
+ sal's here? Can decode_line_1() return more than one
+ sal? If yes, how to match the breakpoint with the
+ multiple sal's ?
+ */
+
for (i = 0; i < sals.nelts; i++)
{
resolve_sal_pc (&sals.sals[i]);
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2005-05-03 17:46 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-05-01 18:33 gdb 6.3 C++ breakpoint in constructor/destructor patch Thomas Maier
2005-05-01 19:05 ` Daniel Jacobowitz
2005-05-01 20:54 ` Thomas Maier
2005-05-01 21:56 ` Daniel Jacobowitz
2005-05-03 17:46 ` Thomas Maier
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox