home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: gnu.gdb.bug
- Path: sparky!uunet!cis.ohio-state.edu!foxtrot.ccmrc.ucsb.edu!doug
- From: doug@foxtrot.ccmrc.ucsb.edu (Douglas Scott)
- Subject: Gdb 4.6 bug report
- Message-ID: <9207222351.AA18283@foxtrot.ccmrc.ucsb.edu>
- Sender: gnulists@ai.mit.edu
- Organization: GNUs Not Usenet
- Distribution: gnu
- Date: Wed, 22 Jul 1992 23:51:03 GMT
- Approved: bug-gdb@prep.ai.mit.edu
- Lines: 748
-
- System: Sun 4/330 Running SunOS 4.1
- Compiler: gcc/g++ 2.2.2
- Gdb version: 4.6, compiled with GCC_MANGLE_BUG flag
- Problems:
- 1) Gdb will not print value returned from overloaded operator [](int), claiming
- structure has no such component (see log).
-
- 2) Gdb dumps core when attempting to print return value of a virtual function called
- from a reference to an object (see log).
-
- Here is a log of two problems, followed by the code. I
- apologize for the length of the code, but it is an extract
- from a 14,000 line program, and I couldnt take the time to
- strip any more out of it. If it is too long for you to deal
- with, let me know, and I will try to extract the problem
- part out.
-
-
- ---
- Douglas Scott (805)893-8352
- Center for Computer Music Research and Composition
- University of California, Santa Barbara
- Internet: (NeXTMail ok) <doug@foxtrot.ccmrc.ucsb.edu>
-
- ######################################################
- (gdb) run
- Starting program: /home/doug/C++/a.out
-
-
- Breakpoint 2, Request::retrieveValues (this=0xf7fffbb8, v=@0xf7fffb78)
- at testit.c:520
- 520 v[valsReturned] = *(valueList->value());
- (gdb) ptype v
- type = class ValueArray {
- private:
- void *array;
- int length_;
- int offset;
-
- public:
- ValueArray(QueryValue *, int);
- struct QueryValue & operator[](int) const;
- int length(void) const;
- } &
- (gdb) print v[valsReturned]
- Structure has no component named operator[].
-
- ######################################################
- gdb a.out
- 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) break 291
- Breakpoint 1 at 0x2a48: file testit.c, line 291.
- (gdb) run
- Starting program: /home/doug/C++/a.out
-
-
- Breakpoint 1, QueryValue::operator= (this=0xf7fffb88, rhs=@0x36040)
- at testit.c:291
- 291 set(rhs.value());
- Warning: the current language does not match this frame.
- (gdb) print rhs
- $1 = (struct QueryValue &) @0x36040: {
- <QueryLabel> = {
- label_ = 0x36060,
-
- _vptr$QueryLabel = 0x32340 <IntValue virtual table>
- },
-
- members of QueryValue:
-
- checkFun = 0x3d64 <posNumsOnly(char)>,
-
- legalValue = 0x3e24 <checkDouble(char *)>
- }
- (gdb) ptype rhs
- type = class QueryValue : public QueryLabel {
- protected:
- int (*checkFun)();
- int (*legalValue)();
-
- public:
- virtual ~QueryValue(void);
- QueryValue(const char *, int (*)(char), int (*)(const char *));
- protected:
- QueryValue(void);
- public:
- virtual char * value(void) const;
- virtual int intValue(void) const;
- virtual double doubleValue(void) const;
- virtual int set(const char *);
- int (*)() charCheckFunction(void);
- protected:
- void operator=(const QueryValue &);
- private:
- virtual int size(void);
- } &
- (gdb) print rhs.value()
- Segmentation fault (core dumped)
-
- tango> gdb ./gdb ~doug/C++/core
- 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...
- Core was generated by `gdb'.
- Program terminated with signal 11, Segmentation fault.
- #0 0x13f88 in unpack_field_as_long (type=0x136518, valaddr=0xf4630 "",
-
- fieldno=-16) at values.c:1222
- 1222 memcpy (&val, valaddr + bitpos / 8, sizeof (val));
- Setting up the environment for debugging gdb.
- Breakpoint 1 at 0x33bd4: file utils.c, line 274.
- Breakpoint 2 at 0x4774: file main.c, line 1658.
- (top-gdb) bt
- #0 0x13f88 in unpack_field_as_long (type=0x136518, valaddr=0xf4630 "",
-
- fieldno=-16) at values.c:1222
- #1 0x137d8 in value_primitive_field (arg1=0xf4608, offset=170831022,
-
- fieldno=-1, arg_type=0x136518) at values.c:863
- #2 0x138a8 in value_field (arg1=0xf4608, fieldno=-1) at values.c:898
- #3 0x13a04 in value_virtual_fn_field (arg1=0xf4608, f=0x136740, j=1271064,
-
- type=0x136518) at values.c:971
- #4 0x181d8 in search_struct_method (name=0xf44b0 "value", arg1=0xf4608,
-
- args=0xf7fff6f4, offset=0, static_memfuncp=0xf7fff768, type=0x136518)
- at valops.c:1095
- #5 0x18690 in value_struct_elt (argp=0xf7fff76c, args=0xf7fff6f4,
-
- name=0xf44b0 "value", static_memfuncp=0xf7fff768, err=0x14928 "structure")
- at valops.c:1222
- #6 0x15224 in evaluate_subexp (expect_type=0x0, exp=0xf4488, pos=0xf7fff7e4,
-
- noside=EVAL_NORMAL) at eval.c:385
- #7 0x148b4 in evaluate_expression (exp=0xf4488) at eval.c:142
- #8 0x1fec4 in print_command_1 (exp=0xe600e "rhs.value()", inspect=0,
-
- voidprint=1) at printcmd.c:752
- #9 0x20020 in print_command (exp=0xe600e "rhs.value()", from_tty=1)
- at printcmd.c:803
- #10 0x3930 in execute_command (p=0xe600e "rhs.value()", from_tty=1)
- at main.c:915
- #11 0x3ae4 in command_loop () at main.c:976
- #12 0x3734 in main (argc=2, argv=0xf7fffc54) at main.c:853
-
-
- ////////////////////////// source for gdb test //////////////////////////
- #include <String.h>
-
- typedef int (*CharCheckFun)(const char);
- typedef int (*LegalValueFun)(const char *);
-
- enum Response {
- Cancel = 0, Yes = 1, No = 2
- };
-
- class String;
-
- struct QueryLabelInfo {
- char *label;
- };
-
- struct QueryButtonInfo {
- char *label; // label for button
- Response response; // behavior for this button (yes, no, cancel)
- };
-
- enum ValueType { None, VString, VInt, VDouble };
-
- struct QueryValueInfo {
- ValueType type;
- char *label;
- char *defaultVal;
- CharCheckFun check;
- LegalValueFun legal;
- };
-
- struct QueryInfo {
- QueryLabelInfo *labelInfo;
- char *valueListLabel;
- QueryValueInfo *valueInfo;
- QueryButtonInfo *buttonInfo;
- };
-
- // base class for all query items, and also used for plain labels
-
- class QueryLabel {
- public:
- QueryLabel(const char *);
- virtual ~QueryLabel();
- const char* label();
- private:
- String *label_;
- };
-
- // class for response buttons (confirm, cancel, etc.)
-
- class QueryButton : public QueryLabel {
- public:
- QueryButton(const char *, Response resp=Yes);
- virtual ~QueryButton();
- virtual Response response() { return response_; }
- virtual int set(Response r) { response_ = r; return 1; }
- private:
- Response response_;
- };
-
- class ValueArray;
-
- // class for querying string, int, or double values
-
- class QueryValue : public QueryLabel {
- public:
- QueryValue(const char *, CharCheckFun ccf, LegalValueFun lvf);
- virtual ~QueryValue();
- virtual const char* value() const = 0;
- virtual const int intValue() const = 0;
- virtual const double doubleValue() const = 0;
- virtual int set(const char *) = 0;
- CharCheckFun charCheckFunction() { return checkFun; }
- void operator = (const QueryValue& rhs);
- protected:
- QueryValue();
- CharCheckFun checkFun;
- LegalValueFun legalValue;
- private:
- friend ValueArray;
- virtual int size() { return sizeof(*this); }
- };
-
- class StringValue : public QueryValue {
- public:
- StringValue(const char *, const char *, CharCheckFun ccf, LegalValueFun lvf);
- StringValue(const char *value=0);
- virtual ~StringValue();
- virtual const char* value() const;
- virtual const int intValue() const;
- virtual const double doubleValue() const;
- virtual int set(const char *);
- private:
- friend ValueArray;
- virtual int size() { return sizeof(*this); }
- String *string;
- };
-
- class IntValue : public QueryValue {
- public:
- IntValue(const char *, const int, CharCheckFun ccf, LegalValueFun lvf);
- IntValue(int value=0);
- virtual ~IntValue();
- virtual const char* value() const;
- virtual const int intValue() const;
- virtual const double doubleValue() const;
- virtual int set(const char *);
- private:
- friend ValueArray;
- virtual int size() { return sizeof(*this); }
- int value_;
- };
-
- class DoubleValue : public QueryValue {
- public:
- DoubleValue(const char *, const double, CharCheckFun ccf, LegalValueFun
- lvf);
- DoubleValue(double value=0.0);
- virtual ~DoubleValue();
- virtual const char* value() const;
- virtual const int intValue() const;
- virtual const double doubleValue() const;
- virtual int set(const char *);
- private:
- friend ValueArray;
- virtual int size() { return sizeof(*this); }
- double value_;
- };
-
- // this allows me to create a virtual array, i.e., it fixes the problem with
- // the array index not adding the correct offset for the derived virtual class
-
- class ValueArray {
- public:
- ValueArray(QueryValue *qa, int len) : array(qa), length_(len) {
- offset = qa->size();
- }
- QueryValue & operator [] (int index) const {
- // check index and return reference to the base class
- index = index < length_ ? index : length_ - 1;
- return *((QueryValue *)(array + offset * index));
- }
- int length() const { return length_; }
- private:
- void *array; // raw pointer to beginning of array
- int length_;
- int offset; // the proper size of each array element
- };
-
- class QueryLabel;
-
- struct QueryLink {
- QueryLink(QueryLabel *q);
- virtual ~QueryLink();
- QueryLabel *element;
- QueryLink *next;
- };
-
- class String;
-
- // linked list container/manipulator for QueryLabel and its derived classes
-
- class QueryList {
- public:
- QueryList(const char *lbl);
- virtual ~QueryList();
- void append(QueryLabel *);
- void start() { current = head; }
- int more() { return current != 0; }
- void next() { current = current->next; }
- const char *label();
- QueryLabel *value() { return current->element; }
- private:
- QueryLink *tail();
- private:
- String *listLabel;
- QueryLink *current;
- QueryLink *head;
- };
-
- class QueryButton;
-
- class ButtonList : public QueryList {
- public:
- ButtonList(const char *lbl=0) : (lbl ? lbl : "") {}
- virtual ~ButtonList() {}
- QueryButton *value() { return (QueryButton *) QueryList::value(); }
- };
-
- class QueryValue;
-
- class ValueList : public QueryList {
- public:
- ValueList(const char *lbl=0) : (lbl ? lbl : "") {}
- virtual ~ValueList() {}
- QueryValue *value() { return (QueryValue *) QueryList::value(); }
- };
-
- enum RequestType { AlertType, ConfirmerType, ChoiceType, InputType };
-
- class DialogConstructor;
- class ValueArray;
-
- class Request {
- friend DialogConstructor;
- public:
- Request() { init(); }
- Request(QueryInfo *);
- virtual ~Request();
-
- int hasLabels() { return labelList != 0; }
- int hasValues() { return valueList != 0; }
- int useBell() { return bell; }
- virtual RequestType type() { return InputType; }
- // default
- void appendLabel(const char *);
- void appendValue(const char *, const char *value, CharCheckFun,
-
- LegalValueFun);
- void appendValue(const char *, int value, CharCheckFun,
-
- LegalValueFun);
- void appendValue(const char *, double value, CharCheckFun,
- LegalValueFun);
- void appendValue(ValueType, const char *, const char *,
- CharCheckFun ccf, LegalValueFun lvf);
- void appendButton(const char *, Response);
- void retrieveValues(ValueArray &v);
- protected:
- virtual void createLabelList(QueryLabelInfo *);
- virtual void createValueList(const char *, QueryValueInfo *);
- virtual void createButtonList(QueryButtonInfo *);
- void setBell(int b) { bell = b; }
- protected:
- QueryList *labelList;
- ValueList *valueList;
- ButtonList *buttonList;
- private:
- void init();
- private:
- int bell; // flag for bell ring
- };
-
- QueryLabel::QueryLabel(const char* lbl) {
- label_ = new String(lbl);
- }
-
- QueryLabel::~QueryLabel() {
- delete label_;
- }
-
- const char*
- QueryLabel::label() { return *label_; }
-
- /////////
-
- QueryButton::QueryButton(const char *lbl, Response r) : (lbl), response_(r) {}
-
- QueryButton::~QueryButton() {}
-
- /////////
-
- // default functions for QueryValue
-
- static int anychar(const char c) { return 1; }
- static int anyvalue(const char *v) { return 1; }
-
- QueryValue::QueryValue(const char* lbl, CharCheckFun ccf, LegalValueFun lvf)
- : (lbl), checkFun(ccf), legalValue(lvf) {}
-
- QueryValue::QueryValue() : (""), checkFun(anychar), legalValue(anyvalue) {}
-
- QueryValue::~QueryValue() {}
-
- void
- QueryValue::operator = (const QueryValue& rhs) {
- // this allows any of the derived classes to be assigned to any other
- // via use of character strings passed between virtual functions
- set(rhs.value());
- }
-
- /////////
-
- StringValue::StringValue(const char *lbl, const char *s, CharCheckFun ccf,
- LegalValueFun lvf) : (lbl, ccf, lvf) {
- string = new String(s ? s : "");
- }
-
- StringValue::StringValue(const char *value) {
- string = new String(value ? value : "");
- }
-
- StringValue::~StringValue() {
- delete string;
- }
-
- int
- StringValue::set(const char *s) {
- register int good = 0;
- if(good = legalValue(s)) {
- *string = (s && strlen(s)) ? s : "0";
- }
- return good;
- }
-
- const char *
- StringValue::value() const {
- return *string;
- }
-
- int
- StringValue::intValue() const {
- return atoi(strlen(*string) > 0 ? *string : "0");
- }
-
- double
- StringValue::doubleValue() const {
- return atof(strlen(*string) > 0 ? *string : "0");
- }
-
- IntValue::IntValue(const char *lbl, const int i, CharCheckFun ccf,
- LegalValueFun lvf) : (lbl, ccf, lvf), value_(i) {}
-
- IntValue::IntValue(int value) : value_(value) {}
-
- IntValue::~IntValue() {}
-
- const char *
- IntValue::value() const {
- static char string[64];
- sprintf(string, "%d", value_);
- return string;
- }
-
- int
- IntValue::intValue() const {
- return value_;
- }
-
- double
- IntValue::doubleValue() const {
- return value_;
- }
-
- int
- IntValue::set(const char *s) {
- register int good = 0;
- if(good = legalValue(s)) {
- value_ = (s && strlen(s)) ? atoi(s) : 0;
- }
- return good;
- }
-
- DoubleValue::DoubleValue(const char *lbl, const double d, CharCheckFun ccf,
- LegalValueFun lvf) : (lbl, ccf, lvf), value_(d) {}
-
- DoubleValue::DoubleValue(double value) : value_(value) {}
-
- DoubleValue::~DoubleValue() {}
-
- const char *
- DoubleValue::value() const {
- static char string[128];
- sprintf(string, "%f", value_);
- return string;
- }
-
- int
- DoubleValue::intValue() const {
- return int(value_);
- }
-
- double
- DoubleValue::doubleValue() const {
- return value_;
- }
-
- int
- DoubleValue::set(const char *s) {
- register int good = 0;
- if(good = legalValue(s)) {
- value_ = (s && strlen(s)) ? atof(s) : 0;
- }
- return good;
- }
-
- QueryLink::QueryLink(QueryLabel *q) {
- element = q;
- next = 0;
- }
-
- QueryLink::~QueryLink() { delete element; }
-
-
- QueryList::QueryList(const char *label) {
- listLabel = new String(label);
- head = 0;
- }
-
- QueryList::~QueryList() {
- delete listLabel;
- start();
- while(current) {
- register QueryLink *next = current->next;
- delete current;
- current = next;
- }
- }
-
- QueryLink *
- QueryList::tail() {
- start();
- while(current && current->next)
- current = current->next;
- return current;
- }
-
- void
- QueryList::append(QueryLabel *q) {
- register QueryLink *link = new QueryLink(q);
- if(!head)
- head = link;
- else
- tail()->next = link;
- current = link;
- }
-
- const char *
- QueryList::label() { return *listLabel; }
-
- ////////
-
- Request::Request(QueryInfo *qinfo) {
- init();
- if(qinfo->labelInfo)
- createLabelList(qinfo->labelInfo);
- if(qinfo->valueInfo)
- createValueList(qinfo->valueListLabel, qinfo->valueInfo);
- if(qinfo->buttonInfo)
- createButtonList(qinfo->buttonInfo);
- }
-
- void
- Request::init() {
- labelList = 0;
- valueList = 0;
- buttonList = 0;
- bell = 0;
- }
-
- Request::~Request() {
- delete labelList;
- delete valueList;
- delete buttonList;
- }
-
- void
- Request::appendLabel(const char *lbl) {
- if(!labelList) labelList = new QueryList("");
- labelList->append(new QueryLabel(lbl));
- }
-
- void
- Request::appendButton(const char *lbl, Response response) {
- if(!buttonList) buttonList = new ButtonList;
- buttonList->append(new QueryButton(lbl, response));
- }
-
- void
- Request::appendValue(const char *label, const char *value, CharCheckFun ccf,
- LegalValueFun lvf) {
- if(!valueList) valueList = new ValueList;
- valueList->append(new StringValue(label, value, ccf, lvf));
- }
-
- void
- Request::appendValue(const char *label, int value, CharCheckFun ccf,
- LegalValueFun lvf) {
- if(!valueList) valueList = new ValueList;
- valueList->append(new IntValue(label, value, ccf, lvf));
- }
-
- void
- Request::appendValue(const char *label, double value, CharCheckFun ccf,
- LegalValueFun lvf) {
- if(!valueList) valueList = new ValueList;
- valueList->append(new DoubleValue(label, value, ccf, lvf));
- }
-
- void
- Request::appendValue(ValueType type, const char *label, const char *defval,
- CharCheckFun ccf, LegalValueFun lvf) {
- if(!valueList) valueList = new ValueList;
- valueList->append(
- type == VString ? new StringValue(label, defval, ccf, lvf)
- : type == VInt ? new IntValue(label, atoi(defval), ccf, lvf)
- : new DoubleValue(label, atof(defval), ccf, lvf)
- );
- }
-
- void
- Request::retrieveValues(ValueArray &v) {
- int valsReturned = 0, nvals = v.length();
- if(hasValues()) {
- for(valueList->start();
- valueList->more() && valsReturned != nvals;
-
- valueList->next(), ++valsReturned) {
- v[valsReturned] = *(valueList->value());
- }
- }
- }
-
- void
- Request::createLabelList(QueryLabelInfo *qlist) {
- for(QueryLabelInfo *i = qlist; i->label != 0; i++) {
- appendLabel(i->label);
- }
- }
-
- void
- Request::createButtonList(QueryButtonInfo *qbilist) {
- for(QueryButtonInfo *i = qbilist; i->label != None; i++) {
- appendButton(i->label, i->response);
- }
- }
-
- void
- Request::createValueList(const char *vlistlabel, QueryValueInfo *qvilist) {
- valueList = new ValueList(vlistlabel);
- for(QueryValueInfo *i = qvilist; i->type != None; i++) {
- appendValue(i->type, i->label, i->defaultVal, i->check,
- i->legal);
- }
- }
-
- // here are the char test functions for checking user input
-
- int
- posIntsOnly(char c) { // control chars and integers only
- return (iscntrl(c) || isdigit(c));
- }
-
- int
- intsOnly(char c) {
- return (c == '-' || posIntsOnly(c));
- }
-
- int
- posNumsOnly(char c) { // control chars, '.', and integers only
- return (c == '.' || posIntsOnly(c));
- }
-
- int
- numsOnly(char c) {
- return (c == '.' || intsOnly(c));
- }
-
- int
- checkDouble(char *s) {
- return 1;
- }
-
- static QueryButtonInfo defaultInputButtonInfo[] = {
- { "confirm", Yes },
- { "cancel", Cancel },
- { 0 }
- };
-
- main() {
- static QueryLabelInfo labels[] = {
- { "Set Endpoints for Horizontal Display: " }, { 0 }
- };
- static QueryInfo info[] = {
- labels, "", 0, defaultInputButtonInfo
- };
- int start = 0;
- int end = 50;
- // create and load a Request object with default values
- Request request(info);
- request.appendValue("Minimum Samp: ", start, posNumsOnly, checkDouble);
- request.appendValue("Maximum Samp: ", end, posNumsOnly, checkDouble);
-
- // normally at this point, the request object would be passed to a
- // dialog creation and display object that queries the user for input
-
- const int nvals = 2;
- IntValue vr[nvals];
-
- // now get the newly set values and load them into vr[]
- // (in this case they are still set to the default values)
-
- request.retrieveValues(ValueArray(vr, nvals));
- printf("Values retrieved are %d and %d\n",
- vr[0].intValue(), vr[1].intValue());
- }
-
-