Article View: gnu.gdb.bug
Article #364(none)
From: Peggy Fieland
Date: Wed, 12 Aug 1992 19:32
Date: Wed, 12 Aug 1992 19:32
379 lines
8766 bytes
8766 bytes
For gdb-4.6 (on a Sun sparc or Stratus FTX), even when demangle-style
is set to cfront, the name of the virtual table is not demangled.
Here is a sample debugging session:
cyclonic-tests% gdb46 zoo
GDB is free software and you are welcome to 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.
GDB 4.6, Copyright 1992 Free Software Foundation, Inc...
(gdb) set demangle-style cfront
(gdb) info var
All defined variables:
File zoo.c:
struct __mptr *__ptbl_vec__zoo_c_insert_[4];
struct __mptr Bear::__vtbl[5];
struct __mptr Lion::__vtbl[5];
struct __mptr Buffalo::__vtbl[5];
struct __mptr __vtbl__9ZooAnimal__zoo_c[5];
static struct Lion *__0__F13;
static struct Bear *__0__F14;
static struct Buffalo *__0__F15;
static struct ZooList alist;
Non-debugging symbols:
00004000 _DYNAMIC
000040b8 environ
000040c0 _ctors
000043b0 _dtors
000043b8 _new_handler
000043c0 edata
000049e8 end
Here is the test program (unfortunately, somewhat long)
extern "C" printf(...);
// Example of virtual functions, class inheritance and overloading!
// By Farooq Butt
extern "C" { // Get the C "strcpy" function
strcpy(char *,char *);
}
enum fruit { apple, orange, banana }; // Herbivore foods
enum meat { rawsteak, bones, groundbeef }; // Carnivore foods
class ZooAnimal {
public:
ZooAnimal(){ printf( "creating a ZooAnimal \n"); strcpy (mytype,"ZooAnimal");}
virtual void draw() { printf( "Generic Zoo Animal\n"); }
virtual void feed(fruit){ printf( "Can't feed a generic Zoo Animal\n");}
virtual void feed(meat) { printf( "Can't feed a generic Zoo Animal\n");}
private:
char mytype[255];
};
class Bear : public ZooAnimal {
public:
Bear (char *whoami = "bear"){strcpy(mytype,whoami);}
void draw();
void feed(fruit);
void feed(meat);
private:
char mytype[255];
};
class Lion : public ZooAnimal{
public:
Lion (char *whoami = "lion"){strcpy(mytype,whoami);}
void draw();
void feed(fruit);
void feed(meat);
private:
char mytype[255];
};
class Buffalo : public ZooAnimal {
public:
Buffalo (char *whoami = "buffalo"){strcpy(mytype,whoami);}
void draw();
void feed(fruit);
void feed(meat);
private:
char mytype[255];
};
// The ZooList is the list object while the ZooItem is the list item
// object. It is VERY important to differentiate between the two because
// a list is a functionally different thing from its components.
class ZooList; // Forward declaration
class ListItem{
friend class ZooList; // i.e. Let the ZooList object get at privates
public:
ListItem(ZooAnimal *v){val = v; next =0;}
private:
ZooAnimal *val;
ListItem *next;
};
class ZooList{
public:
ZooList(){thelist=0;} // constructor
void insert(ZooAnimal*); // interface
void traverse();
private:
ListItem *thelist;
};
void ZooList::insert(ZooAnimal* v)
{
ListItem *pt = new ListItem(v);
pt->next = thelist;
thelist = pt;
}
void ZooList::traverse()
{
if (thelist == 0)
printf( "empty list\n");
ListItem *pt = thelist;
while (pt){
pt->val->draw();
pt->val->feed(apple);
pt->val->feed(rawsteak);
pt=pt->next;
}
}
void Bear::draw()
{
printf( "Grrrrrrraaawr I am a bear\n");
}
void Bear::feed(meat)
{
printf( "YUM YUM, bears love meat!\n");
}
void Bear::feed(fruit)
{
printf( "ECCCCHHH Bears can't eat fruit!\n");
}
void Lion::draw()
{
printf( "Roooooaaaaar I am the king of the forest\n");
}
void Lion::feed(meat)
{
printf( "YUM YUM, lions love meat!\n");
}
void Lion::feed(fruit)
{
printf( "ECCCCHHH Lions can't eat fruit!\n");
}
void Buffalo::draw()
{
printf( "Mooooooo I am the woolly plains-buffalo\n");
}
void Buffalo::feed(meat)
{
printf( "YUK! How could you feed meat to a buffalo!\n");
}
void Buffalo::feed(fruit)
{
printf( "YUM, got any more fruit there ? We buffalos love it!\n");
}
static ZooList alist;
main()
{
static Lion a1;
static Bear a2;
static Buffalo a3;
a1.draw();
a2.draw();
a3.draw();
printf( "\n");
alist.insert(&a1);
alist.insert(&a2);
alist.insert(&a3);
alist.traverse();
}
Here is a fix:
*** /home/tools/gnu/gdb-4.6/gdb/cplus-dem.c Tue Jul 14 03:34:20 1992
--- cplus-dem.c Mon Aug 10 09:58:32 1992
*** 191,196 ****
--- 196,204 ----
static int
gnu_special PARAMS ((string *, const char **, struct work_stuff *));
+ static int
+ cfront_special PARAMS ((string *, const char **, struct work_stuff *));
+
static void
string_need PARAMS ((string *, int));
***************
*** 926,945 ****
/* Mangled name starts with "__". Skip over any leading '_' characters,
then find the next "__" that separates the prefix from the signature.
*/
! while (*scan == '_')
! {
! scan++;
! }
! if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
! {
! /* No separator (I.E. "__not_mangled"), or empty signature
! (I.E. "__not_mangled_either__") */
! success = 0;
! }
! else
! {
! demangle_function_name (declp, mangled, work, scan);
! }
}
else if (*(scan + 2) != '\0')
{
--- 946,970 ----
/* Mangled name starts with "__". Skip over any leading '_' characters,
then find the next "__" that separates the prefix from the signature.
*/
! if ((current_demangling_style != cfront_demangling) ||
! (cfront_special (declp, mangled, work) == 0))
! {
!
! while (*scan == '_')
! {
! scan++;
! }
! if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
! {
! /* No separator (I.E. "__not_mangled"), or empty signature
! (I.E. "__not_mangled_either__") */
! success = 0;
! }
! else
! {
! demangle_function_name (declp, mangled, work, scan);
! }
! }
}
else if (*(scan + 2) != '\0')
{
***************
*** 1033,1038 ****
--- 1058,1124 ----
return (success);
}
+ /*
+
+ LOCAL FUNCTION
+
+ cfront_special -- special handling of gnu mangled strings
+
+ SYNOPSIS
+
+ static int
+ cfront_special (string *declp, const char **mangled,
+ struct work_stuff *work)
+
+
+ DESCRIPTION
+
+ Process some special cfront style mangling forms that don't fit
+ the normal pattern. For example:
+
+ __vtbl_
+
+ */
+
+ static int
+ cfront_special (declp, mangled, work)
+ string *declp;
+ const char **mangled;
+ struct work_stuff *work;
+ {
+ int n, i;
+ int success = 1;
+ const char *p;
+
+ /* account for __vtbl__ -- see above for differences in naming conventions */
+ #define MIN_VTABLE_STRLEN 8
+ #define MIN_OPERATOR_NAME_LEN 6
+ n = strlen(*mangled);
+ if ((n > MIN_VTABLE_STRLEN) && (! memcmp(*mangled,"__vtbl__",8)))
+ {
+ /* Found a cfront style virtual table, get past "__vtbl__
+ and create the decl. Note that we consume the entire mangled
+ input string, which means that demangle_signature has no work
+ to do. */
+ (*mangled) += MIN_VTABLE_STRLEN;
+ get_count(mangled, &i);
+ if (i == 0)
+ success = 0;
+ else
+ {
+ string_appendn (declp, *mangled, i);
+ string_append (declp, " virtual table");
+ n = strlen (*mangled);
+ (*mangled) += n;
+ }
+ }
+ else
+ {
+ success = 0;
+ }
+ return (success);
+ }
+
/* Do a qualified name, such as "Q25Outer5Inner" for "Outer::Inner" */
static int
Technical Details
Message-ID:
<9208121932.AA10286@cyclonic.sw.stratus.com.sw.stratus.com>Path:
arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!cyclonic.sw.stratus.com!pfielandShow Full Headers
Complete Article Headers
Newsgroups: gnu.gdb.bug Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!cyclonic.sw.stratus.com!pfieland From: pfieland@cyclonic.sw.stratus.com (Peggy Fieland) Subject: (none) Message-ID: <9208121932.AA10286@cyclonic.sw.stratus.com.sw.stratus.com> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Wed, 12 Aug 1992 19:32:13 GMT Approved: bug-gdb@prep.ai.mit.edu Lines: 380