public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: Run-time error with virtual function w/o invocation
@ 2012-05-31 17:20 Arthur Schwarz
  2012-05-31 19:12 ` Jonathan Wakely
  2012-05-31 19:50 ` Kalle Olavi Niemitalo
  0 siblings, 2 replies; 7+ messages in thread
From: Arthur Schwarz @ 2012-05-31 17:20 UTC (permalink / raw)
  To: gcc-help; +Cc: Jonathan Wakely

Thank you Jonathan;

I ran the compiler from the shell (g++ -pedantic main.cpp) without any errors or 
warnings and with the same results. I don't think that the method 'new' is in 
error. The segmentation fault does not occur unless the virtual function, fnc, 
is uncommented. If 'fnc' is commented, 'new' executes correctly. I think that 
this might be a compiler bug, but before I waste anyone's time I thought I'd get 
validation that I'm not doing some dumb ol' thing.

art

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Run-time error with virtual function w/o invocation
  2012-05-31 17:20 Run-time error with virtual function w/o invocation Arthur Schwarz
@ 2012-05-31 19:12 ` Jonathan Wakely
  2012-05-31 19:50 ` Kalle Olavi Niemitalo
  1 sibling, 0 replies; 7+ messages in thread
From: Jonathan Wakely @ 2012-05-31 19:12 UTC (permalink / raw)
  To: Arthur Schwarz; +Cc: gcc-help

On May 31, 2012 6:20 PM, "Arthur Schwarz"  wrote:
>
> Thank you Jonathan;
>
> I ran the compiler from the shell (g++ -pedantic main.cpp) without any errors or

That doesn't turn warnings on.

> warnings and with the same results. I don't think that the method 'new' is in
> error.

Which part do you think is correct, the part where you use endl (which
calls flush) then flush again, the part where you don't allocate any
memory, or the part where you forget the return value?

One might be ok, one is pointless but harmless except to performance,
and one is undefined behaviour and is definitely responsible for the
segfault.

> The segmentation fault does not occur unless the virtual function, fnc,
> is uncommented.

You got lucky, it's still undefined behaviour.

> If 'fnc' is commented, 'new' executes correctly.

No, it's still broken.

The reason it appears to work is that you never access anything in the
class, as it has no members. Adding a vtable causes the constructor to
dereference the garbage pointer value you didn't return.

Try adding an int member to the base class, initializing it in the
base constructor, and printing that out. Chances are you'll get a
segfault, virtual function or not.


> I think that
> this might be a compiler bug, but before I waste anyone's time I thought I'd get
> validation that I'm not doing some dumb ol' thing.

I guarantee you haven't found a compiler bug.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Run-time error with virtual function w/o invocation
  2012-05-31 17:20 Run-time error with virtual function w/o invocation Arthur Schwarz
  2012-05-31 19:12 ` Jonathan Wakely
@ 2012-05-31 19:50 ` Kalle Olavi Niemitalo
  2012-05-31 20:40   ` Arthur Schwarz
  1 sibling, 1 reply; 7+ messages in thread
From: Kalle Olavi Niemitalo @ 2012-05-31 19:50 UTC (permalink / raw)
  To: Arthur Schwarz; +Cc: gcc-help

[-- Attachment #1: Type: text/plain, Size: 2665 bytes --]

Arthur Schwarz <aschwarz1309@att.net> writes:

> I ran the compiler from the shell (g++ -pedantic main.cpp) without any errors or 
> warnings and with the same results. I don't think that the method 'new' is in 
> error. The segmentation fault does not occur unless the virtual function, fnc, 
> is uncommented. If 'fnc' is commented, 'new' executes correctly. I think that 
> this might be a compiler bug, but before I waste anyone's time I thought I'd get 
> validation that I'm not doing some dumb ol' thing.

The bug is in your program, as g++-4.7 -Wall warns:

main.cpp: In static member function ‘static void* baseClass::operator new(size_t)’:
main.cpp:7:76: warning: no return statement in function returning non-void [-Wreturn-type]

If you fix that, e.g. by adding "return ::operator new(size);",
then the program will not crash even if you uncomment the virtual
functions.

With the buggy baseClass::operator new, why does it matter
whether the classes have virtual functions?  It's because GCC
implements virtual functions by adding a vtable pointer to each
instance of the class.  The constructors of baseClass and
inheritClass then initialize the vtable pointer.  Because
baseClass::operator new returned something bogus, the "this"
pointer is bogus in these constructors, and they write to some
memory location where they shouldn't.  Judging from the assembly
code generated by GCC, it seems likely that the "this" pointer
points to the std::cout object, which then becomes corrupted and
causes the program to crash.

If you comment out the virtual functions, then there is no vtable
pointer that the constructors would have to initialize.  Because
your constructors don't initialize any data members either, they
don't write to the baseClass or inheritClass object that is being
constructed at the bogus address, thus avoiding the crash.  It
would surely be unwise to rely on such behaviour though.

You can get a similar crash even without virtual functions:

===============================================================================
#include <iostream>

using namespace std;

class baseClass {
public:
   /* buggy code for demonstration purposes */
   static void* operator new(size_t size) { cout << "new" << endl << flush;}
   int x;
   baseClass()  { x = 1; cout << "baseClass constructor" << endl << flush;}
};

int main() {
   new baseClass();
   return 0;
}
===============================================================================

Here, if you remove the x = 1 assignment, it avoids the memory
corruption and the crash, although operator new still won't be right.

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Run-time error with virtual function w/o invocation
  2012-05-31 19:50 ` Kalle Olavi Niemitalo
@ 2012-05-31 20:40   ` Arthur Schwarz
  2012-05-31 21:06     ` Jonathan Wakely
  0 siblings, 1 reply; 7+ messages in thread
From: Arthur Schwarz @ 2012-05-31 20:40 UTC (permalink / raw)
  To: Kalle Olavi Niemitalo; +Cc: gcc-help

Thank Kallie;

You are so right!! Thanks, and thanks for gently telling me how to get 
additional diagnostic information. Much appreciated, and oh by the way, it works 
fine.

art



----- Original Message ----
From: Kalle Olavi Niemitalo <kon@iki.fi>
To: Arthur Schwarz <aschwarz1309@att.net>
Cc: gcc-help@gcc.gnu.org
Sent: Thu, May 31, 2012 12:50:16 PM
Subject: Re: Run-time error with virtual function w/o invocation

Arthur Schwarz <aschwarz1309@att.net> writes:

> I ran the compiler from the shell (g++ -pedantic main.cpp) without any errors 
>or 
>
> warnings and with the same results. I don't think that the method 'new' is in 
> error. The segmentation fault does not occur unless the virtual function, fnc, 

> is uncommented. If 'fnc' is commented, 'new' executes correctly. I think that 
> this might be a compiler bug, but before I waste anyone's time I thought I'd 
>get 
>
> validation that I'm not doing some dumb ol' thing.

The bug is in your program, as g++-4.7 -Wall warns:

main.cpp: In static member function ‘static void* baseClass::operator 
new(size_t)’:
main.cpp:7:76: warning: no return statement in function returning non-void 
[-Wreturn-type]

If you fix that, e.g. by adding "return ::operator new(size);",
then the program will not crash even if you uncomment the virtual
functions.

With the buggy baseClass::operator new, why does it matter
whether the classes have virtual functions?  It's because GCC
implements virtual functions by adding a vtable pointer to each
instance of the class.  The constructors of baseClass and
inheritClass then initialize the vtable pointer.  Because
baseClass::operator new returned something bogus, the "this"
pointer is bogus in these constructors, and they write to some
memory location where they shouldn't.  Judging from the assembly
code generated by GCC, it seems likely that the "this" pointer
points to the std::cout object, which then becomes corrupted and
causes the program to crash.

If you comment out the virtual functions, then there is no vtable
pointer that the constructors would have to initialize.  Because
your constructors don't initialize any data members either, they
don't write to the baseClass or inheritClass object that is being
constructed at the bogus address, thus avoiding the crash.  It
would surely be unwise to rely on such behaviour though.

You can get a similar crash even without virtual functions:

===============================================================================
#include <iostream>

using namespace std;

class baseClass {
public:
   /* buggy code for demonstration purposes */
   static void* operator new(size_t size) { cout << "new" << endl << flush;}
   int x;
   baseClass()  { x = 1; cout << "baseClass constructor" << endl << flush;}
};

int main() {
   new baseClass();
   return 0;
}
===============================================================================

Here, if you remove the x = 1 assignment, it avoids the memory
corruption and the crash, although operator new still won't be right.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Run-time error with virtual function w/o invocation
  2012-05-31 20:40   ` Arthur Schwarz
@ 2012-05-31 21:06     ` Jonathan Wakely
  0 siblings, 0 replies; 7+ messages in thread
From: Jonathan Wakely @ 2012-05-31 21:06 UTC (permalink / raw)
  To: Arthur Schwarz; +Cc: Kalle Olavi Niemitalo, gcc-help

On 31 May 2012 21:39, Arthur Schwarz wrote:
> Thank Kallie;
>
> You are so right!! Thanks, and thanks for gently telling me how to get
> additional diagnostic information. Much appreciated, and oh by the way, it works
> fine.

Don't forget to fix the broken 'operator delete' too or you'll leak
all the memory you allocate.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Run-time error with virtual function w/o invocation
  2012-05-31  4:39 ` Arthur Schwarz
@ 2012-05-31  8:50   ` Jonathan Wakely
  0 siblings, 0 replies; 7+ messages in thread
From: Jonathan Wakely @ 2012-05-31  8:50 UTC (permalink / raw)
  To: Arthur Schwarz; +Cc: gcc-help

On 31 May 2012 05:39, Arthur Schwarz wrote:
>
>
> I'm using g++ 4.5.3 under cygwin using the Netbeans 7.1.1 IDE. A segment
> fault occurs at runtime with the following code.
>
> ==================  code ==================
> #include <iostream>
>
> using namespace std;
>
> class baseClass {
> public:
>   static void* operator new(size_t size) { cout << "new" << endl << flush;};

Try enabling some warnings. This function is broken.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Run-time error with virtual function w/o invocation
       [not found] <1338438456.44262.YahooMailRC@web180814.mail.gq1.yahoo.com>
@ 2012-05-31  4:39 ` Arthur Schwarz
  2012-05-31  8:50   ` Jonathan Wakely
  0 siblings, 1 reply; 7+ messages in thread
From: Arthur Schwarz @ 2012-05-31  4:39 UTC (permalink / raw)
  To: gcc-help



I'm using g++ 4.5.3 under cygwin using the Netbeans 7.1.1 IDE. A segment
fault occurs at runtime with the following code.

==================  code ==================
#include <iostream>

using namespace std;

class baseClass {
public:
   static void* operator new(size_t size) { cout << "new" << endl << flush;};
   static void  operator delete(void* X)    { cout << "delete" << endl << 
flush;}
//   virtual void fnc() { cout << "baseClass fnc" << endl << flush; }
protected:
      baseClass()  { cout << "baseClass constructor" << endl << flush;};
    ~baseClass()  { cout << "baseClass destructor"  << endl << flush;};
};

class inheritClass : public baseClass {
protected:
//   virtual void fnc() { cout << "inheritClass fnc" << endl << flush; }
public:
     inheritClass()  { cout << "inherit constructor" << endl << flush;}
   ~inheritClass()  { cout << "inherit destructor"  << endl << flush;}
};

int main(int argc, char** argv) {
   inheritClass*  inherit;
   inherit    = new inheritClass();
   delete       inherit;
   return 0;
}

===============  end of code ===============

If the virtual function is uncommented then the runtime fails when 'new'  is 
executed. The thread shows entry to the 'operator new' function and
immediate branching to the nheritClass() constructor and immediate
branching to the 'baseClass()' constructor. When the 'baseClass' constructor
is executed a segmentation fault occurs ("Signal received: SIGSEGV
 (Segmentation fault) For  program test, pid 8,652". The code works correctly
 with the virtual  function commented.

I hope that I'm saying things correctly.

After compiling the example program in the cygwin bash shell using 
'g++  main.cpp',  

with the virtual function uncommented, the following stack dump occurrs.:

Exception: STATUS_ACCESS_VIOLATION at eip=5912356C
eax=00000010 ebx=5915ED14 ecx=5915ED14 edx=00000000 esi=0028ABA8 edi=6119FE9F
ebp=0028AB58 esp=0028AB40 program=C:\home\skidmarks\Projects\Test\Test\a.exe, 
pid 8016, thread main
cs=0023 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
Frame     Function  Args
0028AB58  5912356C  (5915ED14, 6119FE9F, 0028AB98, 61102E21)
0028AB78  59123AB6  (0028ABA8, 59160480, BBBAB9B8, 611856C0)
0028ABC8  5914B1AB  (59160480, 00402099, 00000015, 59160480)
0028ABE8   5914EB1E  (59160480, 00402099, 00000003, 00000000)
0028AC08  00401A1B  (59160480, 0040125C, 00000002, 00000000)
0028AC28  004018F2  (59160480, 00000001, 0028FD24, 00000002)
0028AC68  00401198  (00000001, 0028AC90, 80010100, 6127A9A0)
0028ACF8  61007128  (00000000, 0028CD78, 61006720, 00000000)
End of stack trace

Any idea what I can do to fix this thing.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-05-31 21:06 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-31 17:20 Run-time error with virtual function w/o invocation Arthur Schwarz
2012-05-31 19:12 ` Jonathan Wakely
2012-05-31 19:50 ` Kalle Olavi Niemitalo
2012-05-31 20:40   ` Arthur Schwarz
2012-05-31 21:06     ` Jonathan Wakely
     [not found] <1338438456.44262.YahooMailRC@web180814.mail.gq1.yahoo.com>
2012-05-31  4:39 ` Arthur Schwarz
2012-05-31  8:50   ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).