I have a coredump,it shows a reference address is NULL....
details:
(gdb) bt
#0 0xffffe410 in __kernel_vsyscall ()
#1 0x005b6c10 in raise () from /lib/libc.so.6
#2 0x005b8521 in abort () from /lib/libc.so.6
#3 0xf749e641 in Application::fatalSignal () at Application.cc:277
#4 <signal handler called>
#5 SdlProcess::procedureReturn (this=0x0, aSignal=0, aArg1=1, aArg2=0x0)
at /include/c++/4.1.1/bits/stl_list.h:652
#6 0x08112edb in Sdl::authFailurer (aSdlProcess=#0x0, aLabel=0, aSignal=0, arg2=0x0) at /Mgr/SdlAuth.cc:1781
#7 0x00000000 in ?? ()
================
define:
Sdl::authFailurer(SdlProcess& aSdlProcess, int aLabel, int aSignal, int /*arg1*/, void* arg2)
#5 aSdlProcess.procedureReturn(0, 1, 0);
and in stl_list.h:652
bool empty() const
{ return this->_M_impl._M_node._M_next == &this->_M_impl._M_node; } ---->652
in procedureReturn()
{
...
if (!mProcedureStack.empty())---->here,mProcedureStack is a datamember of SdlProcess
...
{
...}
}
You can get a NULL reference by dereferencing a NULL pointer. I'm not sure how that could happen in this particular case, unless mProcedureStack is a reference.
The most often cause of this problem is when you return a dangling reference, such as:
int& foo() {
int bar = 5;
return bar;
}
The returned reference for foo now points to the stack and will contain undefined data.
Related
Example:
#include <assert.h>
int v = 0;
struct Foo {
Foo() { ++v; }
~Foo()
{
--v;
assert(v != 1); // artificially stop the debugger here
}
};
int main()
{
Foo a; // assert in destructor here?
Foo b; // assert in destructor here?
Foo c; // assert in destructor here?
return 0;
} // main()
This code asserts. I think the debugger should be able to tell me which line/instance of Foo is asserting, but it only shows that it's exiting the scope of main():
#6 0x00007ffff7d9ee96 in __GI___assert_fail (assertion=0x555555556019 "v != 1", file=0x555555556010 "main.cpp", line=8,
function=0x555555556004 "Foo::~Foo()") at ./assert/assert.c:101
#7 0x000055555555521c in Foo::~Foo (this=<optimized out>, __in_chrg=<optimized out>) at main.cpp:8
#8 0x00005555555551b6 in main () at main.cpp:17
(gdb) f 8
#8 0x00005555555551b6 in main () at main.cpp:17
17 } // main()
I know the culprit is b, but how can I make gcc tell me?
Is this just a missing feature or is there somethig more fundamental preventing debuggers from showing this information?
If I add a scope for each instance it becomes clear, but I don't think I should have to recompile.
int main()
{
Foo a;
{
Foo b;
{
Foo c;
}
} // <-- backtrace of the assert shows this line
return 0;
}
The same problem exists for members of a class:
class Bar {
Foo a;
Foo b;
Foo c;
};
[EDIT] What I'd really like to see is the debugger stepping back to the line with Foo c; when it returns from main(), then Foo b; etc. Just like what happens in the following example, where the debugger steps through the Baz() lines one at a time before finally entering func().
func(Baz(),
Baz(),
Baz());
but how can I make gcc tell me?
You can't (at least not directly) -- it has no idea that you are interested in this. But you can give each instance of Foo a name it to print the value of this and the name in both constructor and destructor.
You could also get this info from GDB:
Program received signal SIGABRT, Aborted.
__pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=no_tid#entry=0) at ./nptl/pthread_kill.c:44
44 ./nptl/pthread_kill.c: No such file or directory.
(gdb) bt
#0 __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=no_tid#entry=0) at ./nptl/pthread_kill.c:44
#1 0x00007ffff7e55d2f in __pthread_kill_internal (signo=<optimized out>, threadid=<optimized out>) at ./nptl/pthread_kill.c:89
#2 __GI___pthread_kill (threadid=<optimized out>, signo=<optimized out>) at ./nptl/pthread_kill.c:89
#3 0x00007ffff7f9ee70 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x00007ffff7df1472 in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007ffff7df1395 in __assert_fail_base (fmt=<optimized out>, assertion=<optimized out>, file=<optimized out>, line=<optimized out>, function=<optimized out>) at ./assert/assert.c:92
#6 0x00007ffff7dffdf2 in __GI___assert_fail (assertion=0x555555556015 "v != 1", file=0x555555556010 "t.cc", line=10, function=0x555555556004 "Foo::~Foo()") at ./assert/assert.c:101
#7 0x0000555555555200 in Foo::~Foo (this=0x7fffffffd81e, __in_chrg=<optimized out>) at t.cc:10
#8 0x0000555555555183 in main () at t.cc:20
(gdb) fr 8
#8 0x0000555555555183 in main () at t.cc:20
20 } // main()
(gdb) info locals
a = {<No data fields>}
b = {<No data fields>}
c = {<No data fields>}
(gdb) p &a
$1 = (Foo *) 0x7fffffffd81f
(gdb) p &b
$2 = (Foo *) 0x7fffffffd81e <<=== match for this in frame 7
This of course requires that this isn't optimized (as it is in your stack), or that you print the value of this in the destructor.
[EDIT] What I'd really like to see is the debugger stepping back to the line with Foo c; when it returns from main(), then Foo b; etc.
A compiler could in theory do that, but (I suspect) this will be exceedingly confusing to most end-users: "why is the destructor being invoked when I am simply constructing Foo?".
I have following code:
std::thread thread;
EventReceiver target;
{
thread = std::thread([&]() {
auto event = new MyEvent();
QCoreApplication::postEvent(&target, event);
}
});
IdleProcessor::processEvents();
thread.join();
}
Where
class MyEvent : public QEvent, public async::ExecutorEventInterface
{
public:
MyEvent()
: QEvent(QEvent::User){
};
void execute() override
{
}
};
class EventReceiver : public QObject
{
Q_OBJECT
public:
EventReceiver();
/**
* #brief receives the MainExecutor posted event
* #param event
* #return
*/
bool event(QEvent* event) override
{
auto myEvent = dynamic_cast<ExecutorEventInterface*>(event);
if (myEvent)
{
myEvent->execute();
return true;
}
return false;
}
};
I get thread sanitizer report, and don't figure out why.
==================
WARNING: ThreadSanitizer: data race on vptr (ctor/dtor vs virtual call) (pid=56278)
Read of size 8 at 0x7b0800026018 by main thread:
#0 async::EventReceiver::event(QEvent*) eventreceiver.cpp:16 (unittests:x86_64+0x107353775)
#1 QCoreApplicationPrivate::notify_helper(QObject*, QEvent*) <null> (QtCore:x86_64+0x1ea917)
#2 AsyncTest_test_Test::TestBody() async_tests.cpp:103 (unittests:x86_64+0x1004fa8f3)
#3 void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) <null> (unittests:x86_64+0x1042addbd)
#4 TestApplication::event(QEvent*) testapplication.cpp:20 (unittests:x86_64+0x1041f89cf)
#5 QCoreApplicationPrivate::notify_helper(QObject*, QEvent*) <null> (QtCore:x86_64+0x1ea917)
#6 start <null> (libdyld.dylib:x86_64+0x163d4)
Previous write of size 8 at 0x7b0800026018 by thread T4:
#0 async::ExecutorEventInterface::ExecutorEventInterface() executoreventinterface.h:9 (unittests:x86_64+0x10058dd10)
#1 MyEvent::MyEvent() async_tests.cpp:73 (unittests:x86_64+0x100599466)
#2 MyEvent::MyEvent() async_tests.cpp:74 (unittests:x86_64+0x1005993e8)
#3 AsyncTest_test_Test::TestBody()::$_6::operator()() const async_tests.cpp:98 (unittests:x86_64+0x100599322)
#4 void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, AsyncTest_test_Test::TestBody()::$_6> >(void*) type_traits:4428 (unittests:x86_64+0x100598fb5)
Location is heap block of size 32 at 0x7b0800026000 allocated by thread T4:
#0 operator new(unsigned long) <null> (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x6d723)
#1 AsyncTest_test_Test::TestBody()::$_6::operator()() const async_tests.cpp:98 (unittests:x86_64+0x100599308)
#2 void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, AsyncTest_test_Test::TestBody()::$_6> >(void*) type_traits:4428 (unittests:x86_64+0x100598fb5)
Thread T4 (tid=424005, finished) created by main thread at:
#0 pthread_create <null> (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x2936d)
#1 std::__1::thread::thread<AsyncTest_test_Test::TestBody()::$_6, void>(AsyncTest_test_Test::TestBody()::$_6&&) __threading_support:336 (unittests:x86_64+0x100598642)
#2 std::__1::thread::thread<AsyncTest_test_Test::TestBody()::$_6, void>(AsyncTest_test_Test::TestBody()::$_6&&) thread:360 (unittests:x86_64+0x1004faa88)
#3 AsyncTest_test_Test::TestBody() async_tests.cpp:94 (unittests:x86_64+0x1004fa81e)
#4 void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) <null> (unittests:x86_64+0x1042addbd)
#5 TestApplication::event(QEvent*) testapplication.cpp:20 (unittests:x86_64+0x1041f89cf)
#6 QCoreApplicationPrivate::notify_helper(QObject*, QEvent*) <null> (QtCore:x86_64+0x1ea917)
#7 start <null> (libdyld.dylib:x86_64+0x163d4)
SUMMARY: ThreadSanitizer: data race on vptr (ctor/dtor vs virtual call) eventreceiver.cpp:16 in async::EventReceiver::event(QEvent*)
Why that happens considering that EventReceiver is created in a thread and than posted to the main thread, seems to be a race on virtual method execute but at that point object is fully constructed.
LATER EDIT
This seems to be a benign race though. The sanitizer does not know/see that EventReceiver::event(QEvent* event) happens after/is caused by using QCoreApplication::postEvent(&target, event), which happens after MyEvent is constructed (because MyEvent instance is input to QCoreApplication::postEvent)
I can add explicit fencing for this to be clear to the sanitizer but this seems excessive ? Wonder if it's recommended to just use some annotations to disable this.
I have got one crash. and I use gdb to analyze the stack,I got the below result.
13 0x00007f423c6e9670 in ?? ()
#14 0x00007f42340496d8 in ?? ()
#15 0x0000000003cef568 in ?? ()
#16 0x00000000008da861 in HuffmanEnd ()
#17 0x00000000008d4a83 in faacEncClose ()
#18 0x00000000004fd797 in RecorderSession::~RecorderSession (this=0x7f423404ea90, __in_chrg=<value optimized out>)
at /root/Desktop/VideoRecoder/2.0/src/videorecorder/RecorderSession.cpp:203
#19 0x00000000004fdae9 in RecorderSession::~RecorderSession (this=0x7f423404ea90, __in_chrg=<value optimized out>)
at /root/Desktop/VideoRecoder/2.0/src/videorecorder/RecorderSession.cpp:203
#20 0x0000000000500d0b in RecorderSession::OnHangup (this=0x7f423404ea90) at /root/Desktop/VideoRecoder/2.0/src/videorecorder/RecorderSession.cpp:295
#21 0x000000000045e083 in CSipPhone::on_call_state (call_id=2, e=<value optimized out>)
As we see, the crash happens in the HuffmanEnd. But I don't understand why the ~RecorderSession is called twice although I use code "delete this" to delete the RecorderSession object as below:
int RecorderSession::OnHangup()
{
delete this;
return 0;
}
So does the "delete this" cause this phenomenon?
The chances are that your function OnHangup itself is already being called from the destructor of the object in question. Thus you are calling delete on yourself when the object is already in the middle of being destroyed, causing the double delete.
It seems your object is created by placement new, or as a local object on the stack, or as a namespace-scope / global, or as a member of another object.
In that case Dtor will be called one more time.
I am making a simple sorting program with templates and are struggling with string case.
Code:
template<typename typ>
void Join_Segments(typ *tab, int begin1, int begin2, int end2, bool(*Compare)(typ arg1, typ arg2)){
typ *joined = new typ[end2-begin1+1]; // sorted elements arrray
int c1, c2, ci; // counters
for(c1=begin1, c2=begin2, ci=0; c1<begin2 && c2<=end2; ci++){
if(!Compare(tab[c1], tab[c2])){ joined[ci]=tab[c2]; c2++;}
else{ joined[ci]=tab[c1]; c1++;}
}
while(c1<begin2){joined[ci]=tab[c1]; c1++; ci++;}
while(!(c2>end2)){joined[ci]=tab[c2]; c2++; ci++;}
for(int i=0; i<(end2-begin1+1); i++) tab[begin1+i]=joined[i];
delete joined;
}
So this is working wonderful for integers. And it is working for strings as long as I remove the "delete joined" line, but that is pretty crucial for sorting large arrays.
GDB backtrace log:
Program terminated with signal SIGABRT, Aborted.
#0 0x40022424 in __kernel_vsyscall ()
(gdb) bt
#0 0x40022424 in __kernel_vsyscall ()
#1 0x40171827 in __GI_raise (sig=sig#entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#2 0x40174c53 in __GI_abort () at abort.c:89
#3 0x401ac993 in __libc_message (do_abort=do_abort#entry=1,
fmt=fmt#entry=0x402a9a5c "*** Error in `%s': %s: 0x%s ***\n")
at ../sysdeps/posix/libc_fatal.c:175
#4 0x401b6e7a in malloc_printerr (action=<optimized out>,
str=0x402a9a80 "munmap_chunk(): invalid pointer", ptr=0x90551d4)
at malloc.c:4996
#5 0x401b6f48 in munmap_chunk (p=<optimized out>) at malloc.c:2816
#6 0x400849df in operator delete(void*) ()
from /usr/lib/i386-linux-gnu/libstdc++.so.6
#7 0x08049518 in Join_Segments<std::string> (tab=0x905500c, begin1=0, begin2=2,
end2=2, Compare=0x80490a6 <_GLOBAL__sub_I__Z2Nli()+8>) at scalanie.hh:11
#8 0x080491f5 in Mergesort<std::string> (tab=0x905500c, begin=0,
end=2, Compare=0x80490a6 <_GLOBAL__sub_I__Z2Nli()+8>) at scalanie.hh:32
#9 0x08048ee1 in main () at main.cpp:11
I think this is probably caused by std::string assignment magic but I can't figure out how to fix it. Tried a lot of things like casting right hand side of assigment to (const typ&) so it will copy it according to that documentation but it's still trying blindly. Could anyone help me with this?
I can provide full code but it's not visually identical (english is not my native language and I changed functions/var names here) so it may be harder to read.
Thanks!
You should use delete[] since you are deleting an array allocated with new[]. Mixing incorrect types of new/delete can lead to undefined behavior according to the standard which I guess is what you are seeing.
In the following backtrace from a core dump A2:~A2 is called twice:
#0 0x086f5371 in B1::~B1 (this=0xe6d3a030,
__in_chrg=<value optimized out>)
at /fullpath/b1.cpp:400
#1 0x086ffd43 in ~B2 (this=0xe6d3a030,
__in_chrg=<value optimized out>)
at /fullpath/b2.h:21
#2 B2::~B2 (this=0xe6d3a030,
__in_chrg=<value optimized out>)
at /fullpath/b2.h:21
#3 0x086ea516 in A1::~A1 (this=0xe3e93958,
__in_chrg=<value optimized out>)
at /fullpath/a1.cpp:716
#4 0x0889b85d in A2::~A2 (this=0xe3e93958,
__in_chrg=<value optimized out>)
at /fullpath/a2.cpp:216
#5 0x0889b893 in A2::~A2 (this=0xe3e93958,
__in_chrg=<value optimized out>)
at /fullpath/a2.cpp:216
#6 0x0862c0f1 in E::Identify (this=0xe8083e20, t=PT_UNKNOWN)
at /fullpath/e.cpp:713
A2 is derived from A1 and B2 is derived from B1. Only B2 has a default destructor, all base class destructors are virtual.
The code looks something like this:
e.cpp:
E::E(){
//... some code ...
myA1= new A2();
}
void E::Identify(){
//...
if(myA1){
delete myA1; //line 713 of e.cpp
myA1 = NULL;
}
}
a2.cpp:
A2::~A2(){
//...
if (sd) //sd is not null here and also not made null after deletion
{
delete [] sd; //when called the second time shouldn't it crash here?
}
//...
} // line 216 of a2.cpp
a1.cpp
A1::A1(){
//...
myB1 = new B2();
//...
}
A1::~A1(){
//...
delete myB1; //line 716 of a1.cpp
//...
}
I cannot understand why A2::~A2 is called twice for the same object ( the this pointer in the backtrace has the same value for both 4 and 5 frames).
If I go to frame 4 and disassemble it prints a very different result from the frame 5 disassembeled code (about 90 lines of assembly code vs about 20 lines of assembly code).
I minimalized the example to
#include <cassert>
class A1 {
public:
virtual ~A1() {
assert(false);
}
};
class A2 : public A1 {
};
int main() {
A1* a = new A2;
delete a;
return 0;
}
with the assert to trigger a core dump.
Compiling with g++ 4.7.2, we get the double destructor backtrace in gdb
#0 0x00007f16060e92c5 in raise () from /usr/lib/libc.so.6
#1 0x00007f16060ea748 in abort () from /usr/lib/libc.so.6
#2 0x00007f16060e2312 in __assert_fail_base () from /usr/lib/libc.so.6
#3 0x00007f16060e23c2 in __assert_fail () from /usr/lib/libc.so.6
#4 0x00000000004007c8 in A1::~A1 (this=0xf60010, __in_chrg=<optimized out>) at double.cpp:6
#5 0x000000000040084d in A2::~A2 (this=0xf60010, __in_chrg=<optimized out>) at double.cpp:10
#6 0x0000000000400880 in A2::~A2 (this=0xf60010, __in_chrg=<optimized out>) at double.cpp:10
#7 0x000000000040078c in main () at double.cpp:15
while the backtrace of the same code compiled with g++ 4.3.2 looks similar but with only one frame for A2::~A2.
Both backtraces extracted with the same version of gdb (7.5.1).
So it is an artifact of the code generated by g++ 4.7, nothing to worry about for the behaviour of the compiled binary. It is not a real double call to the destructor.
This could be your scenario (but you didn't show us this part of the code)...
If class E holds a private member pointer to A2, and it doesn't have a copy constructor or operator= ....
Then, there could be a situation where an Object of type E is copied to another object (variable) of type E with the default copy constructor or operator =.
That will cause shallow copying of members, which will cause both objects to now point to the same object A1.
When the object E's are destroyed, they both try to delete the same A2 object.