gcc 6.1.0 segmentation fault - gcc bug?

不羁岁月 提交于 2020-01-05 04:58:35

问题


Let's consider follwing code. In fact this is narrowed problem I found using gmock and mocking void(void) method.

class Base {
 public:
  virtual ~Base() {}
};

class Derived : public Base
{
 public:
  void GetValueAndDelete()  { delete this; } //here we crash
};

int main() {
  Derived* p = 0;
  p->GetValueAndDelete();
}

Building it with:

/tools/gcc6.1/bin/g++ --version
g++ (GCC) 6.1.0

with optimization level different than -O0 and running the result causes segmentation fault.

Is it gcc bug or something with c++ code (yes, yes, I know that it uses side effects, but it works with other compilers and without optimization as well)


回答1:


Is it gcc bug

No.

or something with c++ code

Yes. You use the arrow operator on a pointer that doesn't point to a valid object. This has undefined behaviour.

Dereferencing null pointer and calling method in this way that does not use any members is fine.

It's not fine according to the standard. It's UB.

What is calling method on pointer?

Is implementation specific.

Deleting this is nothing special.

Deleting this is very special.

You should only take care of not using any member after

Yes, that and you must make sure that only new was used to create all instances on which the function is ever called. No automatic objects, no static objects no new[], no malloc + placement new.

So yes, you can delete this, but be careful.




回答2:


Your intuition here seems to be:

  1. p-> is OK because it is just a syntax for filling in this.
  2. delete this is OK because you don't use this after delete.

But the above may not actually be OK, because dereferencing a null pointer is always undefined behavior. Without optimization enabled this may not cause any trouble, because the compiler is doing a "basic compile" which somewhat matches what you imagine when you "compile in your mind." With optimization, however, GCC will do a lot of things that it normally would not do, such as not bothering to emit "correct" instructions when faced with incorrect source code. There's literally no need for it to do anything at all when you say p-> as your program's first act--it could just pretend main() was empty (or crash, as in your case).




回答3:


I know that calling method on nullptr is out of standard, but so far I haven't seen a compiler that wouldn't cope with that in described manner. It seems that gcc6.1 works different (still according to spec). So this is gmock bug. I wonder how many other projects depend on such compiler behavior :)

What is worth to mention is that method is called, 'this' inside is zero as expected and then delete fails. I looked into assembly an there is mov (%rax), %rbx which fails because rax contains zero.



来源:https://stackoverflow.com/questions/38352381/gcc-6-1-0-segmentation-fault-gcc-bug

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!