debug/7078: debug info is not generated correctly with c++ namespaces are used
salman.khilji@cae.com
salman.khilji@cae.com
Wed Jun 19 09:19:00 GMT 2002
>Number: 7078
>Category: debug
>Synopsis: debug info is not generated correctly with c++ namespaces are used
>Confidential: no
>Severity: critical
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Wed Jun 19 07:06:03 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: Salman A Khilji
>Release: Reading specs from d:/mingw/bin/../lib/gcc-lib/mingw32/3.1/specs Configured with: ../gcc/configure --with-gcc --with-gnu-ld --with-gnu-as --host=mingw32 --target=mingw32 --prefix=/mingw --enable-threads --disable-nls --enable-languages=f
>Organization:
>Environment:
Windows 2000, MingW Pentium III and Mandrake Linux 8.1.
>Description:
When c++ namespaces are used, the generated debug information in the stabs format is not correct. As a result of this utilities like objdump don't work correctly. Version 2.95 of gcc works better than version 3.1. I have included a detailed step by step instructions on how to reproduce this bug in the source-code comments
>How-To-Repeat:
compile with g++ -g -o hello.exe main.cpp
and then run objdump -g hello.exe > hello_exe_dump.txt
With the latest version of g++ (3.1) and objdump (2.12.90), objdump refuses to list the debug info
>Fix:
:-(
>Release-Note:
>Audit-Trail:
>Unformatted:
77,c++,objc,ada --disable-win32-registry --disable-shared Thread model: win32 gcc version 3.1
----gnatsweb-attachment----
Content-Type: text/plain; name="main.cpp"
Content-Disposition: inline; filename="main.cpp"
#include <iostream>
using namespace std;
//
// If you have any question about this, please contact
// salman.khilji@cae.com
//
// This is very import to us as we are developing an application
// that needs to have access to the symbol table of the generated
// executable (its a debugger type of application). I know that
// current version of GDB has problem with the following
// type of code---this may as very well be a result of the bug
// that I am going to describe.
//
// When using GDB { GNU gdb 5.1.1 (mingw experimental) } you can type
//
// whatis g_aLEADLAG
//
// but the following does not work
//
// whatis NAMESPC_VARIABLES::g_aLEADLAG
//
// I don't know whether the bug is in gcc, binutils, or
// bfd, so I suppose I am going to post it to several
// bug tracking systems.
//
// This example illustrates the bug in gcc when creating
// debug information when namespaces are used. We create
// a slightly different class named LEADLAD in two different
// namespaces. Then we create two variables of these types
// in the global namespace and two in the namespace named
// NAMESPC_VARIABLES. We assign different values to all
// 4 instances and print them out. This works as expected
// in the program output.
//
// The debug information, however, is wrong.
//
//
// Lets follow this step by step: (Notice that I am using precompiled
// binaries from the MingW site, so I don't know what ./configuration
// settings they used.
//
//
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// 1)
//
// using MingW on Windows 2000:
// g++ --version 2.95.3-6
// objdump --version 2.11.90
//
//
// compile this program as:
//
// g++ -g -o hello.exe main.cpp
// objdump -g hello.exe > hello_exe_dump.txt
//
// Result: almost correct
//
// Following are the relevant lines from hello_exe_dump.txt
//
// class LEADLAG { /* size 40 id 3 */
// public:
// float m_Float; /* bitsize 32, bitpos 0 */
// char m_Name[30]; /* bitsize 240, bitpos 32 */
// long unsigned int m_Zip; /* bitsize 32, bitpos 288 */
// . . .
// class LEADLAG /* id 3 */ *class LEADLAG /* id 3 */::LEADLAG () /* __Q211NAMESPC_FOO7LEADLAG */;
// . . .
// };
// typedef class LEADLAG /* id 3 */ LEADLAG;
// class LEADLAG { /* size 48 id 4 */
// public:
// float m_Float; /* bitsize 32, bitpos 0 */
// char m_Name[30]; /* bitsize 240, bitpos 32 */
// long unsigned int m_Zip; /* bitsize 32, bitpos 288 */
// double m_AdditionalDouble; /* bitsize 64, bitpos 320 */
// . . .
// class LEADLAG /* id 4 */ *class LEADLAG /* id 4 */::LEADLAG () /* __Q211NAMESPC_BAR7LEADLAG */;
// . . .
// };
// typedef class LEADLAG /* id 4 */ LEADLAG;
// . . .
// LEADLAG g_aLEADLAG /* 0x413000 */;
// LEADLAG g_bLEADLAG /* 0x413040 */;
// LEADLAG _17NAMESPC_VARIABLES$g_aLEADLAG /* 0x413080 */;
// LEADLAG _17NAMESPC_VARIABLES$g_bLEADLAG /* 0x4130c0 */;
//
//
// Notice that our 4 variables are listed above. The addresses reported are all different
// since they are 4 different variables. All four variables, however are reported to have the type LEADLAG.
// We know that this is not correct. The first variable is of type NAMESPC_FOO::LEADLAG, the second is
// NAMESPC_BAR::LEADLAG. The 3rd and 4th are the same is the 1st and 2nd respectively.
//
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// 2)
//
// using MingW on Windows 2000:
// g++ --version 3.1
// objdump --version 2.12.90
//
//
// compile this program as:
//
// g++ -g -o hello.exe main.cpp
// objdump -g hello.exe > hello_exe_dump.txt
//
// Result: error :-( objdump refuses to generate the output file
//
// Following are the errors
//
// D:\SoftDev\GCC\simple>objdump -g hello.exe > hello_exe_dump.txt
// bad mangled name `ZNSt11char_traitsIcE6assignERcRKc'
// Last stabs entries before error:
// n_type n_desc n_value string
// LSYM 125 00000000 wistringstream:t(7,39)=(7,40)=xsbasic_istringstream<wchar_t,std::char_traits<wchar_t>,s
// td::allocator<wchar_t> >:
// LSYM 126 00000000 wostringstream:t(7,41)=(7,42)=xsbasic_ostringstream<wchar_t,std::char_traits<wchar_t>,s
// td::allocator<wchar_t> >:
// LSYM 127 00000000 wstringstream:t(7,43)=(7,44)=xsbasic_stringstream<wchar_t,std::char_traits<wchar_t>,std
// ::allocator<wchar_t> >:
// LSYM 128 00000000 wfilebuf:t(7,45)=(7,46)=xsbasic_filebuf<wchar_t,std::char_traits<wchar_t> >:
// LSYM 129 00000000 wifstream:t(7,47)=(7,48)=xsbasic_ifstream<wchar_t,std::char_traits<wchar_t> >:
// LSYM 130 00000000 wofstream:t(7,49)=(7,50)=xsbasic_ofstream<wchar_t,std::char_traits<wchar_t> >:
// LSYM 131 00000000 wfstream:t(7,51)=(7,52)=xsbasic_fstream<wchar_t,std::char_traits<wchar_t> >:
// EINCL 0 00000000
// BINCL 0 0000157a d:/mingw/include/g++-v3/exception
// LSYM 72 00000000 terminate_handler:t(54,1)=(54,2)=*(54,3)=f(15,8)
// LSYM 74 00000000 unexpected_handler:t(54,4)=(54,2)
// EINCL 0 00000000
// BINCL 0 000175d6 d:/mingw/include/g++-v3/bits/char_traits.h
// BINCL 0 00000000 d:/mingw/include/g++-v3/cstring
// EINCL 0 00000000
// LSYM 138 00000000 char_traits<char>:Tt(55,1)=s1operator=::(55,2)=#(55,1),(55,3)=&(55,1),(55,4)=*(55,1),(5
// 5,5)=&(55,6)=k(55,1),(15,8);:_ZNSt11char_traitsIcEaSERKS0_;2A.;__base_ctor::(55,7)=#(55,1),(15,8),(55,4),(55,5
// ),(15,8);:_ZNSt11char_traitsIcEC2ERKS0_;2A.;__comp_ctor::(55,7):_ZNSt11char_traitsIcEC1ERKS0_;2A.;__base_ctor:
// :(55,8)=#(55,1),(15,8),(55,4),(15,8);:_ZNSt11char_traitsIcEC2Ev;2A.;__comp_ctor::(55,8):_ZNSt11char_traitsIcEC
// 1Ev;2A.;assign::(55,9)=f(15,8):_ZNSt11char_traitsIcE6assignERcRKc;2A?;eq::(55,10)=f(0,21):_ZNSt11char_traitsIc
// E2eqERKcS2_;2A?;lt::(55,10):_ZNSt11char_traitsIcE2ltERKcS2_;2A?;compare::(55,11)=f(0,1):_ZNSt11char_traitsIcE7
// compareEPKcS2_j;2A?;length::(55,12)=f(14,2):_ZNSt11char_traitsIcE6lengthEPKc;2A?;find::(55,13)=f(55,14)=*(55,1
// 5)=k(0,2):_ZNSt11char_traitsIcE4findEPKcjRS1_;2A?;move::(55,16)=f(15,2):_ZNSt11char_traitsIcE4moveEPcPKcj;2A?;
// copy::(55,16):_ZNSt11char_traitsIcE4copyEPcPKcj;2A?;assign::(55,17)=f(15,2):_ZNSt11char_traitsIcE6assignEPcjc;
// 2A?;to_char_type::(55,18)=f(0,2):_ZNSt11char_traitsIcE12to_char_typeERKi;2A?;to_int_type::(55,19)=f(0,1):_ZNSt
// 11char_traitsIcE11to_int_typeERKc;2A?;eq_int_type::(55,20)=f(0,21):_ZNSt11char_traitsIcE11eq_int_typeERKiS2_;2
// A?;eof::(47,19):_ZNSt11char_traitsIcE3eofEv;2A?;not_eof::(55,21)=f(0,1):_ZNSt11char_traitsIcE7not_eofERKi;2A?;
// ;
//
//
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// 3)
//
// Since step 2 failed with the latest version of g++, lets try something
//
// comment out the very first two lines at the top of this file, namely
//
// #include <iostream> (line 1)
// using namespace std; (line 2)
//
// Then comment out the lines that say:
//
// cout << m_Float << endl; (line 241 and 254)
//
// using MingW on Windows 2000:
// g++ --version 3.1
// objdump --version 2.12.90
//
//
// compile this program as:
//
// g++ -g -o hello.exe main.cpp
// objdump -g hello.exe > hello_exe_dump.txt
//
// Result: at least objdump now generates the output file, but the output file
// is wrong!!!
//
// Following are the relevant sections:
//
// class LEADLAG { /* size 40 id 2 */
// public:
// float m_Float; /* bitsize 32, bitpos 0 */
// char m_Name[30]:uint32; /* bitsize 240, bitpos 32 */
// long unsigned int m_Zip; /* bitsize 32, bitpos 288 */
// . . .
// void class LEADLAG /* id 2 */::__base_ctor (class LEADLAG /* id 2 */ *) /* _ZN11NAMESPC_FOO7LEADLAGC2Ev */;
// . . .
// };
// typedef class LEADLAG /* id 2 */ LEADLAG;
// class LEADLAG { /* size 48 id 3 */
// public:
// float m_Float; /* bitsize 32, bitpos 0 */
// char m_Name[30]:uint32; /* bitsize 240, bitpos 32 */
// long unsigned int m_Zip; /* bitsize 32, bitpos 288 */
// double m_AdditionalDouble; /* bitsize 64, bitpos 320 */
// . . .
// void class LEADLAG /* id 3 */::__base_ctor (class LEADLAG /* id 3 */ *) /* _ZN11NAMESPC_BAR7LEADLAGC2Ev */;
// . . .
// };
// typedef class LEADLAG /* id 3 */ LEADLAG;
//
// LEADLAG g_aLEADLAG /* 0x40e020 */;
// LEADLAG g_bLEADLAG /* 0x40e060 */;
// LEADLAG g_aLEADLAG /* 0x40e020 */;
// LEADLAG g_bLEADLAG /* 0x40e060 */;
//
//
// Okay...at least objump generated the information, but the 1st and 3rd variables are reported to have the
// same address!!! (we know this is not the case, they are two distinct variables!) The same is true of the
// 2nd and 4th. Also the comment mentioned in step 1 is still true---all 4 variables seem to have the same
// type; however, we know that these LEADLAG structures are in different namespaces.
//
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// 4)
//
// I tried a variation of the above. Before submitting the bug report I compiled with -save-temps option
// Also I renamed the global variables that I created in the namespace from g_aLEADLAG and g_bLEADLAG to
// g_cLEADLAG and g_dLEADLAG respectively so that these variables would not conflict with the variables
// created in the global namespace.
//
// Then I looked at the generated .s file (stabs debug info) and I was suprised to see that g_cLEADLAG,
// and g_dLEADLAG did not exist in the .s file!
//
// I tried this with
//
// using MingW on Windows 2000:
// g++ --version 3.1
// objdump --version 2.12.90
//
// namespace NAMESPC_VARIABLES {
// NAMESPC_FOO::LEADLAG g_cLEADLAG; // renamed from g_aLEADLAG
// NAMESPC_BAR::LEADLAG g_dLEADLAG; // renamed g_bLEADLAG
// }
namespace NAMESPC_FOO {
class LEADLAG {
public:
float m_Float;
char m_Name[30];
unsigned long int m_Zip;
void print() {
cout << m_Float << endl;
}
};
}
namespace NAMESPC_BAR {
class LEADLAG {
public:
float m_Float;
char m_Name[30];
unsigned long int m_Zip;
double m_AdditionalDouble;
void print() {
cout << m_Float << endl;
}
};
}
NAMESPC_FOO::LEADLAG g_aLEADLAG;
NAMESPC_BAR::LEADLAG g_bLEADLAG;
namespace NAMESPC_VARIABLES {
NAMESPC_FOO::LEADLAG g_aLEADLAG;
NAMESPC_BAR::LEADLAG g_bLEADLAG;
}
int main()
{
g_aLEADLAG.m_Float = 45.0F;
g_bLEADLAG.m_Float = 145.0F;
NAMESPC_VARIABLES::g_aLEADLAG.m_Float = 1045.0F;
NAMESPC_VARIABLES::g_bLEADLAG.m_Float = 2145.0F;
g_aLEADLAG.print();
g_bLEADLAG.print();
NAMESPC_VARIABLES::g_aLEADLAG.print();
NAMESPC_VARIABLES::g_bLEADLAG.print();
return 0;
}
More information about the Gcc-bugs
mailing list