This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

GDB and EGCS, problems stepping in shared libraries.


[i sent this to gdb-bugs and egcs-bugs but have yet to see a copy of
 this from egcs-bugs list server.  I think egcs-bugs was listed on the
 cc: line instead of on the to: line so i suspect the listserver there
 ate it.  attempt #2]
--------------------------------------

  Hello all,

  Recently we have been having problems using gdb on egcs-1.0.1 compiled
c++ programs... one problem involves stepping into functions while 
in shared library code.  I have included a small sample program to
reproduce the problem on both Linux and Sparc platforms as well
as an example run of gdb on both shared and static executables.

  Are there any patches that fix this problem?

  If there are any questions, just let me know...

======================================
platforms: 
  Linux myth 2.0.30 #3 Sun Aug 24 18:45:01 EDT 1997 i586 unknown
  SunOS mercury 5.5 Generic_103093-02 sun4u sparc SUNW,Ultra-1

g++: egcs-2.90.23 980102 (egcs-1.0.1 release)
gas: GNU assembler 970915
gld: GNU ld 2.8.2
gdb: GDB 4.16p1 (sparc-sun-solaris2.5), 
gdb: GDB 4.16p1 (i586-unknown-linux),

note: 
  binutils and gdb on both systems were recompiled with egcs once egcs
was installed and working.  recompiling gdb with egcs reportedly fixed 
some of the weird behavior people had seen.

======================================
  this is how the tests were made... on both architectures.
is the shared library built correctly?

  g++ -g -Wall -c main.cc -o s_main.o
  g++ -g -Wall -c foo.cc -o s_foo.o
  g++ -g -Wall s_main.o s_foo.o -o statictest
  g++ -fPIC -g -Wall -c main.cc -o d_main.o
  g++ -fPIC -g -Wall -c foo.cc -o d_foo.o
  g++ -g -Wall d_foo.o -shared -o libFoo.so
  g++ -g -Wall d_main.o -L. -lFoo -o dynamictest

this shows the static executable being traced correctly:
======================================
  gdb ./statictest:
  GDB 4.16p1 (i586-unknown-linux), 
  (gdb) b main
  Breakpoint 1 at 0x8048672: file main.cc, line 5.
  (gdb) r
  Starting program: /home/msimons/bug1/./statictest 

  Breakpoint 1, main () at main.cc:5
  5         Foo test;
  (gdb) s
  Foo::Foo (this=0xbffffd27) at foo.cc:7
  7         Bar ();
  (gdb) s
  Foo::Bar (this=0xbffffd27) at foo.cc:12
  12        fprintf (stderr, "here we are!\n");
  (gdb) n
  here we are!
  13      }
  (gdb) 
  Foo::Foo (this=0xbffffd27) at foo.cc:8
  8       }
  (gdb) 
  main () at main.cc:7
  7         test.Bar();
  (gdb) s
  Foo::Bar (this=0xbffffd27) at foo.cc:12
  12        fprintf (stderr, "here we are!\n");
  (gdb) n
  here we are!
  13      }
  (gdb) 
  main () at main.cc:9
  9         return 0;
  (gdb) c
  Continuing.

  Program exited normally.
======================================

the dynamic one fails to step while in the constructor:
======================================
  msimons@myth:~/bug1> echo $LD_LIBRARY_PATH 
  /home/msimons/bug1
  msimons@myth:~/bug1> gdb ./dynamictest 
  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.16p1 (i586-unknown-linux), 
  Copyright 1996 Free Software Foundation, Inc...
  (gdb) b main
  Breakpoint 1 at 0x80485af: file main.cc, line 5.
  (gdb) r
  Starting program: /home/msimons/bug1/./dynamictest 

  Breakpoint 1, main () at main.cc:5
  5         Foo test;
  (gdb) s
  Foo::Foo (this=0xbffffd4f) at foo.cc:7
  7         Bar ();
  (gdb) 
  ===*********************=== here we are trying to step into method Bar
  here we are!
  8       }
  ===*********************===
  (gdb) 
  main () at main.cc:7
  7         test.Bar();
  (gdb) 
  Foo::Bar (this=0xbffffd4f) at foo.cc:12
  12        fprintf (stderr, "here we are!\n");
  (gdb) n
  here we are!
  13      }
  (gdb) c
  Continuing.

  Program exited normally.
======================================
to reproduce the problem:

  This code is supposed to demonstrate a problem stepping into a second
method from a first method of a class... but only when the class is 
linked as a shared library.

  Step into the constructor and try to step into the Bar method 
which exists in the constructor... in the static version you will 
be at a fprintf statement.  In the dynamic version the fprintf will 
happen and you will be at the return point of the constructor 
(Foo::Bar happens without you).


Makefile:
======================================
# Compiler and Compiler Options
CXX = g++
CXXFLAGS = -g -Wall -fcheck-memory-usage

# Make Target
all: statictest dynamictest

statictest: s_main.o s_foo.o
	$(CXX) $(CXXFLAGS) $^ -o $@

dynamictest: d_main.o libFoo.so
	$(CXX) $(CXXFLAGS) $< -L. -lFoo -o $@

# Clean Objects and Target
clean:
	rm -f *.o

nuke: clean
	rm -f statictest dynamictest libFoo.so

### rules
s_main.o: main.cc foo.h
	$(CXX) $(CXXFLAGS) -c $< -o $@

s_foo.o: foo.cc foo.h
	$(CXX) $(CXXFLAGS) -c $< -o $@

d_main.o: main.cc foo.h
	$(CXX) -fPIC $(CXXFLAGS) -c $< -o $@

d_foo.o: foo.cc foo.h
	$(CXX) -fPIC $(CXXFLAGS) -c $< -o $@

libFoo.so: d_foo.o
	$(CXX) $(CXXFLAGS) $^ -shared -o $@

======================================


foo.cc
======================================
#include <stdio.h>

#include "foo.h"

Foo::Foo ()
{
  Bar ();
}

void Foo::Bar (void)
{
  fprintf (stderr, "here we are!\n");
}
======================================

foo.h
======================================
#ifndef _FOO_H_
#define _FOO_H_

class Foo
{
  public:
    Foo ();
    void Bar(void);
};
#endif
======================================

main.cc
======================================
#include "foo.h"

int main ()
{
  Foo test;

  test.Bar();

  return 0;
}
======================================

-- 

  Any suggestions are appreciated,

      Mike Simons
      Science Applications International Corporation
      msimons@saic1.com                  703-925-5674

ps:
  ... there is one remaining problem that i am tring to get an example
of.  in c++ code the debugger often doesn't know what type variables 
are, so they get printed as "<error type>" or some such...
i have seen a few other people report a similar problem.  
would a example (like this message) help trackdown/solve this problem?  
or is it's cause well known?


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]