* Problem with "next" in main on sparc
@ 1999-11-01 11:38 Jim Kingdon
1999-11-08 16:28 ` Jason Molenda
0 siblings, 1 reply; 2+ messages in thread
From: Jim Kingdon @ 1999-11-01 11:38 UTC (permalink / raw)
To: gdb-patches
Here is a bug in which GDB gets in an infinite loop.
The problem was with the following change. I'm not sure what the
rationale for this change was, and I will point out that the code
which was checked in didn't match the ChangeLog entry. In fact the
code would seem to disable most uses of the ->frame field, so it would
look like it causes problems other than this one.
1998-09-08 Jason Molenda (jsm@bugshack.cygnus.com)
* breakpoint.c (bpstat_stop_status): Declare a bp match if the
current fp matches the bp->fp OR if the current fp is less than
the bp->fp if we're looking at a bp_step_resume breakpoint.
After the test case I have enclosed a patch to revert the 1998-09-08
change.
[kingdon@bart jakub]$ cat try.c
int foo = 1;
int main(void)
{
foo = 2;
}
[kingdon@bart jakub]$ gcc -g try.c
[kingdon@bart jakub]$ ./gdb-6 a.out
GNU gdb 19991004
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "sparc-redhat-linux"...
(gdb) b main
Breakpoint 1 at 0x103a8: file try.c, line 4.
(gdb) run
Starting program: /home/devel/kingdon/zwork/jakub/a.out
Breakpoint 1, main () at try.c:4
4 foo = 2;
(gdb) next
5 }
(gdb)
[infinite loop, hit ^C]
Program received signal SIGINT, Interrupt.
0x70049f00 in __libc_start_main () at ../sysdeps/generic/libc-start.c:120
120 ../sysdeps/generic/libc-start.c: No such file or directory.
(gdb) quit
The program is running. Exit anyway? (y or n) y
1999-08-13 Jim Kingdon < http://developer.redhat.com/ >
* breakpoint.c (bpstat_stop_status): Revert 1998-09-08 change
to ->frame matching. The change did not match the ChangeLog
entry, looked fishy, and caused infinite stepping when running
"next" from main on sparc. Thanks to Jakub for the report.
[kingdon@bart gdb]$ diff -u breakpoint.c.orig breakpoint.c
--- breakpoint.c.orig Mon Oct 4 21:35:17 1999
+++ breakpoint.c Mon Nov 1 14:09:41 1999
@@ -2345,9 +2345,8 @@
real_breakpoint = 1;
}
- if (b->frame && b->frame != (get_current_frame ())->frame &&
- (b->type == bp_step_resume &&
- (INNER_THAN (get_current_frame ()->frame, b->frame))))
+ if (b->frame &&
+ b->frame != (get_current_frame ())->frame)
bs->stop = 0;
else
{
From crash@cygnus.com Mon Nov 01 12:04:00 1999
From: Jason Molenda <crash@cygnus.com>
To: Jim Kingdon <kingdon@redhat.com>
Cc: gdb-patches@sourceware.cygnus.com
Subject: Re: Problem with "next" in main on sparc
Date: Mon, 01 Nov 1999 12:04:00 -0000
Message-id: <19991101120357.B5862@cygnus.com>
References: <199911011938.OAA32716@devserv.devel.redhat.com>
X-SW-Source: 1999-q4/msg00138.html
Content-length: 2978
On Mon, Nov 01, 1999 at 02:38:31PM -0500, Jim Kingdon wrote:
>
> 1998-09-08 Jason Molenda (jsm@bugshack.cygnus.com)
>
> * breakpoint.c (bpstat_stop_status): Declare a bp match if the
> current fp matches the bp->fp OR if the current fp is less than
> the bp->fp if we're looking at a bp_step_resume breakpoint.
Ack, ill considered changes come back to haunt me. :-) Let me look
this over later today so I can figure out if I'm a dork or not before
I comment in depth. I'm fully prepared to admit a mistake, but I want
to look it over a little more closely to figure out what I was doing.
FWIW here in my original summary of the problem:
When you do a 'step' on the last line in a function, the program runs
without stopping. This is because Purify inserts calls to the Purify
code right in the program epilogue. GDB detects these calls out to code
with no line numbers, sets a step_resume_breakpoint on the instruction
following the branch insn, and runs the inferior until it hits the
breakpoint.
The problem is where the FP has already been rolled back--we're right at
the very end of the epilogue and we make one more call to the Purify code.
When the breakpoint set after the branch is hit, bpstat_stop_status sees
that there is a breakpoint at $pc, but bpstat_stop_status() checks the
FP in the breakpoint (b->frame) against the current FP.
The FP in the breakpoint is the correct one for our function, but the
current FP has been rolled back to the caller function already--they do
not match. w_f_i does not remove the gdb_step_resume breakpoint and does
another PT_CONTINUE via ptrace() because it thinks it still has to hit
the breakpoint. The program continues until it exits.
Why did the frame address get set incorrectly in the breakpoint? We set
the step_resume_breakpoint _after_ we find outself in the no-line-number
code (see the code around "/* A subroutine call has happened. */"
in w_f_i()). set_momentary_breakpoint() sets up the breakpoint for us
at the SAVED_PC_AFTER_CALL address and we set the 'frame' member of the
breakpoint to be step_frame_address.
And here is the cvs log message I added when I checked this in:
With a bp_step_resume type breakpoint, the frame pointer check exists in
case we recurse and execute the same text section--we want to not stop
there because it would confuse the user. So gdb checks to see that the
frame pointer matches the one recorded in the breakpoint.
If the current frame pointer is less than the frame pointer recorded in
the breakpoint, then something odd is happened and we should declare that
we're at the breakpoint so that we clear it out.
This happens in Purify instrumented executables on PA systems, at least.
They insert some calls out to Purify code in the function epilogue and
it confuses GDB (which assumes that the frame pointer does not move
around through the entire execution of a function).
Jason
From guo@cup.hp.com Mon Nov 01 12:16:00 1999
From: Jimmy Guo <guo@cup.hp.com>
To: gdb-patches@sourceware.cygnus.com
Subject: (patch) hpjyg04: c-typeprint.c c-valprint.c
Date: Mon, 01 Nov 1999 12:16:00 -0000
Message-id: <Pine.LNX.4.10.9911011212380.30664-100000@hpcll168.cup.hp.com>
X-SW-Source: 1999-q4/msg00139.html
Content-length: 6308
Small patch for c-typeprint.c and c-typeprint.c -- see ChangeLog.
- Jimmy Guo, guo@cup.hp.com
Index: gdb/ChangeLog
/opt/gnu/bin/diff -r -c -N /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/ChangeLog gdb/ChangeLog
*** /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/ChangeLog Mon Nov 1 11:30:10 1999
--- gdb/ChangeLog Mon Nov 1 12:10:23 1999
***************
*** 1,4 ****
--- 1,12 ----
1999-11-01 Jimmy Guo <guo@cup.hp.com>
+ * c-typeprint.c
+ (c_type_print_varspec_prefix,c_type_print_varpsec_suffix): Add
+ TYPE_CODE_TEMPLATE case and default case.
+ (c_type_print_base): Revise how demangled_no_class is found;
+ print '}' before printing local file:line info.
+ * c-valprint.c (c_value_print): print reference type to class.
+
+ 1999-11-01 Jimmy Guo <guo@cup.hp.com>
* buildsym.h (add_free_pendings): Declare.
Index: gdb/c-typeprint.c
/opt/gnu/bin/diff -r -c -N /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/c-typeprint.c gdb/c-typeprint.c
*** /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/c-typeprint.c Fri Oct 29 16:09:22 1999
--- gdb/c-typeprint.c Fri Oct 29 16:25:52 1999
***************
*** 338,346 ****
--- 338,350 ----
case TYPE_CODE_BITSTRING:
case TYPE_CODE_COMPLEX:
case TYPE_CODE_TYPEDEF:
+ case TYPE_CODE_TEMPLATE:
/* These types need no prefix. They are listed here so that
gcc -Wall will reveal any types that haven't been handled. */
break;
+ default:
+ error ("type not handled in c_type_print_varspec_prefix()");
+ break;
}
}
***************
*** 530,538 ****
--- 534,546 ----
case TYPE_CODE_BITSTRING:
case TYPE_CODE_COMPLEX:
case TYPE_CODE_TYPEDEF:
+ case TYPE_CODE_TEMPLATE:
/* These types do not need a suffix. They are listed so that
gcc -Wall will report types that may not have been considered. */
break;
+ default:
+ error ("type not handled in c_type_print_varspec_suffix()");
+ break;
}
}
***************
*** 766,772 ****
if (TYPE_HAS_VTABLE (type) && (STREQN (TYPE_FIELD_NAME (type, i), "__vfp", 5)))
continue;
/* Other compilers */
- /* pai:: FIXME : check for has_vtable < 0 */
if (STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5)
&& is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
continue;
--- 774,779 ----
***************
*** 924,936 ****
else
{
char *p;
! char *demangled_no_class = demangled_name;
! while ((p = strchr (demangled_no_class, ':')))
! {
! demangled_no_class = p;
! if (*++demangled_no_class == ':')
! ++demangled_no_class;
}
/* get rid of the static word appended by the demangler */
p = strstr (demangled_no_class, " static");
--- 931,943 ----
else
{
char *p;
! char *demangled_no_class = strrchr (demangled_name, ':');
! if (demangled_no_class == NULL)
! demangled_no_class = demangled_name;
! else
! {
! ++demangled_no_class; /* skip over last ':' */
}
/* get rid of the static word appended by the demangler */
p = strstr (demangled_no_class, " static");
***************
*** 955,966 ****
}
}
if (TYPE_LOCALTYPE_PTR (type) && show >= 0)
fprintfi_filtered (level, stream, " (Local at %s:%d)\n",
TYPE_LOCALTYPE_FILE (type),
TYPE_LOCALTYPE_LINE (type));
-
- fprintfi_filtered (level, stream, "}");
}
if (TYPE_CODE (type) == TYPE_CODE_TEMPLATE)
goto go_back;
--- 962,973 ----
}
}
+ fprintfi_filtered (level, stream, "}");
+
if (TYPE_LOCALTYPE_PTR (type) && show >= 0)
fprintfi_filtered (level, stream, " (Local at %s:%d)\n",
TYPE_LOCALTYPE_FILE (type),
TYPE_LOCALTYPE_LINE (type));
}
if (TYPE_CODE (type) == TYPE_CODE_TEMPLATE)
goto go_back;
Index: gdb/c-valprint.c
/opt/gnu/bin/diff -r -c -N /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/c-valprint.c gdb/c-valprint.c
*** /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/c-valprint.c Fri Oct 29 15:49:26 1999
--- gdb/c-valprint.c Mon Nov 1 12:05:17 1999
***************
*** 483,502 ****
{
/* Pointer to class, check real type of object */
fprintf_filtered (stream, "(");
! type = value_rtti_target_type (val, &full, &top, &using_enc);
! if (type)
{
/* RTTI entry found */
! type = lookup_pointer_type (type);
! type_print (type, "", stream, -1);
! }
! else
! {
! /* No RTTI fields, do whatever we can */
! type = VALUE_ENCLOSING_TYPE (val);
! type_print (type, "", stream, -1);
! fprintf_filtered (stream, " ?");
! }
fprintf_filtered (stream, ") ");
}
else
--- 483,506 ----
{
/* Pointer to class, check real type of object */
fprintf_filtered (stream, "(");
! real_type = value_rtti_target_type (val, &full, &top, &using_enc);
! if (real_type)
{
/* RTTI entry found */
! if (TYPE_CODE (type) == TYPE_CODE_PTR)
! {
! /* create a pointer type pointing to the real type */
! type = lookup_pointer_type (real_type);
! }
! else
! {
! /* create a reference type referencing the real type */
! type = lookup_reference_type (real_type);
! }
! /* Note: When we look up RTTI entries, we don't get any
! information on const or volatile attributes */
! }
! type_print (type, "", stream, -1);
fprintf_filtered (stream, ") ");
}
else
***************
*** 521,526 ****
--- 525,532 ----
/* Print out object: enclosing type is same as real_type if full */
return val_print (VALUE_ENCLOSING_TYPE (val), VALUE_CONTENTS_ALL (val), 0,
VALUE_ADDRESS (val), stream, format, 1, 0, pretty);
+ /* Note: When we look up RTTI entries, we don't get any information on
+ const or volatile attributes */
}
else if (type != VALUE_ENCLOSING_TYPE (val))
{
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Problem with "next" in main on sparc
1999-11-01 11:38 Problem with "next" in main on sparc Jim Kingdon
@ 1999-11-08 16:28 ` Jason Molenda
0 siblings, 0 replies; 2+ messages in thread
From: Jason Molenda @ 1999-11-08 16:28 UTC (permalink / raw)
To: Jim Kingdon; +Cc: gdb-patches
On Mon, Nov 01, 1999 at 02:38:31PM -0500, Jim Kingdon wrote:
> Here is a bug in which GDB gets in an infinite loop.
I am sorry I took so long to reply. I resolved to look into this before
I sent out this week's snapshot.
I tried reproducing it on a SPARC Solaris box with gcc and I didn't have
the problem described. AFAIK we don't have a SPARC RH box locally so I
can't test that. The GCC I was using is not one of the FSF releasese,
it is similar to the GCC working sources around February or March.
Maybe you show me the end bit of try.s if you compile "gcc -S -g try.c"
on your side? I'm getting this here:
main:
.stabn 68,0,3,.LM1-main
.LM1:
!#PROLOGUE# 0
save %sp, -112, %sp
!#PROLOGUE# 1
.stabn 68,0,4,.LM2-main
.LM2:
sethi %hi(foo), %o1
or %o1, %lo(foo), %o0
mov 2, %o1
st %o1, [%o0]
.stabn 68,0,5,.LM3-main
.LM3:
.LL2:
ret
restore
.LLfe1:
.size main,.LLfe1-main
.LLscope0:
Which GDB (current development version) handles correctly:
; ./gdb -q a.out
(gdb) b main
Breakpoint 1 at 0x10704: file try.c, line 4.
(gdb) run
Starting program: /horton/jsm/comp-tools/i-sparc/bin/a.out
Breakpoint 1, main () at try.c:4
4 foo = 2;
(gdb) n
5 }
(gdb)
0x105fc in .nope ()
(gdb)
Single stepping until exit from function .nope,
which has no line number information.
Program exited with code 01.
(gdb)
Jason
From guo@cup.hp.com Tue Nov 09 10:00:00 1999
From: Jimmy Guo <guo@cup.hp.com>
To: gdb-patches@sourceware.cygnus.com
Subject: (patch) hpjyg16: valarith.c
Date: Tue, 09 Nov 1999 10:00:00 -0000
Message-id: <Pine.LNX.4.10.9911090950260.8268-100000@hpcll168.cup.hp.com>
X-SW-Source: 1999-q4/msg00211.html
Content-length: 6524
This patch adds support for exponentiation, and (in)equality of boolean /
string.
ChangeLog:
1999-11-09 Jimmy Guo <guo@cup.hp.com>
* valarith.c (value_binop): Add support for exponentiation,
equal, not equal.
(my_strcmp): New function.
(value_equal,value_less): Add string equality comparison support.
Index: gdb/valarith.c
/opt/gnu/bin/diff -r -c -N /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/valarith.c gdb/valarith.c
*** /view/guo.wdb.c//CLO/Components/WDB/Src/gnu/gdb/valarith.c Mon Nov 8 16:02:14 1999
--- gdb/valarith.c Mon Nov 8 16:07:05 1999
***************
*** 28,33 ****
--- 28,34 ----
#include "language.h"
#include "demangle.h"
#include "gdb_string.h"
+ #include <math.h>
/* Define whether or not the C operator '/' truncates towards zero for
differently signed operands (truncation direction is undefined in C). */
***************
*** 573,579 ****
value_concat (arg1, arg2)
value_ptr arg1, arg2;
{
! register value_ptr inval1, inval2, outval;
int inval1len, inval2len;
int count, idx;
char *ptr;
--- 574,580 ----
value_concat (arg1, arg2)
value_ptr arg1, arg2;
{
! register value_ptr inval1, inval2, outval = NULL;
int inval1len, inval2len;
int count, idx;
char *ptr;
***************
*** 738,744 ****
/* FIXME-if-picky-about-floating-accuracy: Should be doing this
in target format. real.c in GCC probably has the necessary
code. */
! DOUBLEST v1, v2, v;
v1 = value_as_double (arg1);
v2 = value_as_double (arg2);
switch (op)
--- 739,745 ----
/* FIXME-if-picky-about-floating-accuracy: Should be doing this
in target format. real.c in GCC probably has the necessary
code. */
! DOUBLEST v1, v2, v = 0;
v1 = value_as_double (arg1);
v2 = value_as_double (arg2);
switch (op)
***************
*** 759,764 ****
--- 760,771 ----
v = v1 / v2;
break;
+ case BINOP_EXP:
+ v = pow (v1, v2);
+ if (errno)
+ error ("Cannot perform exponentiation: %s", strerror (errno));
+ break;
+
default:
error ("Integer-only operation on floating point number.");
}
***************
*** 779,785 ****
&&
TYPE_CODE (type2) == TYPE_CODE_BOOL)
{
! LONGEST v1, v2, v;
v1 = value_as_long (arg1);
v2 = value_as_long (arg2);
--- 786,792 ----
&&
TYPE_CODE (type2) == TYPE_CODE_BOOL)
{
! LONGEST v1, v2, v = 0;
v1 = value_as_long (arg1);
v2 = value_as_long (arg2);
***************
*** 795,800 ****
--- 802,815 ----
case BINOP_BITWISE_XOR:
v = v1 ^ v2;
+ break;
+
+ case BINOP_EQUAL:
+ v = v1 == v2;
+ break;
+
+ case BINOP_NOTEQUAL:
+ v = v1 != v2;
break;
default:
***************
*** 855,861 ****
if (unsigned_operation)
{
! ULONGEST v1, v2, v;
v1 = (ULONGEST) value_as_long (arg1);
v2 = (ULONGEST) value_as_long (arg2);
--- 870,876 ----
if (unsigned_operation)
{
! ULONGEST v1, v2, v = 0;
v1 = (ULONGEST) value_as_long (arg1);
v2 = (ULONGEST) value_as_long (arg2);
***************
*** 884,889 ****
--- 899,910 ----
v = v1 / v2;
break;
+ case BINOP_EXP:
+ v = pow (v1, v2);
+ if (errno)
+ error ("Cannot perform exponentiation: %s", strerror (errno));
+ break;
+
case BINOP_REM:
v = v1 % v2;
break;
***************
*** 949,954 ****
--- 970,979 ----
v = v1 == v2;
break;
+ case BINOP_NOTEQUAL:
+ v = v1 != v2;
+ break;
+
case BINOP_LESS:
v = v1 < v2;
break;
***************
*** 976,982 ****
}
else
{
! LONGEST v1, v2, v;
v1 = value_as_long (arg1);
v2 = value_as_long (arg2);
--- 1001,1007 ----
}
else
{
! LONGEST v1, v2, v = 0;
v1 = value_as_long (arg1);
v2 = value_as_long (arg2);
***************
*** 996,1001 ****
--- 1021,1032 ----
case BINOP_DIV:
v = v1 / v2;
+ break;
+
+ case BINOP_EXP:
+ v = pow (v1, v2);
+ if (errno)
+ error ("Cannot perform exponentiation: %s", strerror (errno));
break;
case BINOP_REM:
***************
*** 1125,1130 ****
--- 1156,1192 ----
return len < 0;
}
+ /* Perform a comparison on two string values (whose content are not
+ necessarily null terminated) based on their length */
+
+ static int
+ my_strcmp (arg1, arg2)
+ register value_ptr arg1, arg2;
+ {
+ int len1 = TYPE_LENGTH (VALUE_TYPE (arg1));
+ int len2 = TYPE_LENGTH (VALUE_TYPE (arg2));
+ char *s1 = VALUE_CONTENTS (arg1);
+ char *s2 = VALUE_CONTENTS (arg2);
+ int i, len = len1 < len2 ? len1 : len2;
+
+ for (i = 0; i < len; i++)
+ {
+ if (s1[i] < s2[i])
+ return -1;
+ else if (s1[i] > s2[i])
+ return 1;
+ else
+ continue;
+ }
+
+ if (len1 < len2)
+ return -1;
+ else if (len1 > len2)
+ return 1;
+ else
+ return 0;
+ }
+
/* Simulate the C operator == by returning a 1
iff ARG1 and ARG2 have equal contents. */
***************
*** 1175,1180 ****
--- 1237,1246 ----
}
return len < 0;
}
+ else if (code1 == TYPE_CODE_STRING && code2 == TYPE_CODE_STRING)
+ {
+ return my_strcmp (arg1, arg2) == 0;
+ }
else
{
error ("Invalid type combination in equality test.");
***************
*** 1217,1223 ****
return value_as_pointer (arg1) < (CORE_ADDR) value_as_long (arg2);
else if (code2 == TYPE_CODE_PTR && (code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL))
return (CORE_ADDR) value_as_long (arg1) < value_as_pointer (arg2);
!
else
{
error ("Invalid type combination in ordering comparison.");
--- 1283,1290 ----
return value_as_pointer (arg1) < (CORE_ADDR) value_as_long (arg2);
else if (code2 == TYPE_CODE_PTR && (code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL))
return (CORE_ADDR) value_as_long (arg1) < value_as_pointer (arg2);
! else if (code1 == TYPE_CODE_STRING && code2 == TYPE_CODE_STRING)
! return my_strcmp (arg1, arg2) < 0;
else
{
error ("Invalid type combination in ordering comparison.");
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~1999-11-08 16:28 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-11-01 11:38 Problem with "next" in main on sparc Jim Kingdon
1999-11-08 16:28 ` Jason Molenda
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox