I am currently trying to wrap an std::ostringstream into and std::unique_ptr.
My current code compiles, but at runtime, I am getting an segmentation fault.
When I do not wrap it - using an old c-style pointer, it runs fine.
For a more detailed overview, I am downloading data using curlpp into an ostringstream.
This is what I am doing:
std::unique_ptr< std::ostringstream > data_stream;
curlpp::Cleanup myCleanup;
*data_stream << curlpp::options::Url(this->m_ressource_url);
The segmentation fault occurs at the last line, this is the backtrace:
0x00007ffff790e2ce in std::ostream::sentry::sentry(std::ostream&) () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/libstdc++.so.6
(gdb) bt
#0 0x00007ffff790e2ce in std::ostream::sentry::sentry(std::ostream&) () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/libstdc++.so.6
#1 0x00007ffff790e3f7 in std::ostream::write(char const*, long) () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/libstdc++.so.6
#2 0x0000000000429be6 in curlpp::internal::Callbacks::StreamWriteCallback (buffer=0x660d1b "Das ist (k)ein Test.", size=1, nitems=20, stream=0x0)
at OptionSetter.cpp:55
#3 0x00007ffff7b90678 in ?? () from /usr/lib64/libcurl.so.4
#4 0x00007ffff7ba4d38 in ?? () from /usr/lib64/libcurl.so.4
#5 0x00007ffff7bac967 in ?? () from /usr/lib64/libcurl.so.4
#6 0x00007ffff7bad5e5 in curl_multi_perform () from /usr/lib64/libcurl.so.4
#7 0x00007ffff7ba5dd6 in curl_easy_perform () from /usr/lib64/libcurl.so.4
#8 0x0000000000425a78 in curlpp::internal::CurlHandle::perform (this=0x6690b0) at CurlHandle.cpp:52
#9 0x0000000000424fca in curlpp::Easy::perform (this=0x7fffffffd5c0) at Easy.cpp:48
#10 0x00000000004252ba in operator<< (stream=..., request=...) at Easy.cpp:116
#11 0x0000000000424d7f in operator<< (stream=..., url=...) at Options.cpp:34
#12 0x0000000000420bb1 in Model<std::string>::m_download (this=0x7fffffffd878)
at /home/bueddl/Developement/Studium/Semester 4/SWT/Source/model/src/Model.hpp:98
#13 0x0000000000420a4e in Model<std::string>::refresh (this=0x7fffffffd878)
at /home/bueddl/Developement/Studium/Semester 4/SWT/Source/model/src/Model.hpp:71
#14 0x00000000004206a5 in main () at /home/bueddl/Developement/Studium/Semester 4/SWT/Source/model/src/main.cpp:56
FYI, my files are from #14 to #12, the code above is a part of the file #12.
Now, this is strange, when I am writing the fallowing code, it works without problems:
std::ostringstream *data_stream = new std::ostringstream();
curlpp::Cleanup myCleanup;
*data_stream << curlpp::options::Url(this->m_ressource_url);
Both cases are passing pointers to the operator<<, but I seem to be wrong.
Where am I wrong?
Thanks for your help :)
Note: I wanted to use the unique_ptr for implementing sink-source pattern.
unique_ptr doesn't automatically create an instance of the pointed to object. You still need to do that yourself. So your code is trying to use a NULL pointer to a stream.
You need to do something like:
std::unique_ptr< std::ostringstream > data_stream(new std::ostringstream);
curlpp::Cleanup myCleanup;
*data_stream << curlpp::options::Url(this->m_ressource_url);
Related
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.
I have a crash with signal 6 aborted on new operator with the following callstack:
> #0 0x00f6d00b in __kernel_vsyscall ()
> #1 0x009fdbaa in ____strtoull_l_internal () from /lib/libc.so.6
> #2 0x009ff44a in ____strtof_l_internal () from /lib/libc.so.6
> #3 0x00a3bbb5 in _IO_default_pbackfail_internal () from /lib/libc.so.6
> #4 0x00a46671 in memalign () from /lib/libc.so.6
> #5 0x00a4235f in _obstack_newchunk () from /lib/libc.so.6
> #6 0x00a4334e in strverscmp () from /lib/libc.so.6
> #7 0x083d54cd in operator new (size=1160) at /home/build/exp.cpp:8145
> #8 .............
What are the possible reasons I can end up with this? The memory usage of my machine is quite low, about 8% of 12GB, I don't think memory is an issue ( the core dump is about 700MB ).
The new operator is overloaded to use malloc:
void * operator new (size_t size) throw()
{
return malloc(size);
}
You most likely overrun an new'd/malloc'ed block earlier, destroying the book-keeping data malloc uses, hence it crashes the next time you try to malloc something.
You should compile with all warnings and debug info (e.g. g++ -Wall -g) then use valgrind.
Your implementation of new is wrong. malloc can fail, and in that case your new should throw an exception. It is not allowed to return NULL
If your GCC is recent, consider also using -fsanitize=address
I have an application using QtWebKit. It loads URLs and exports some stats on the render trees. This section of code is causing problems:
...
if (mPage != 0) {
disconnectSignals(mPage);
delete mPage;
}
mPage = new Page(); //subclass of QWebPage
connectSignals(mPage);
QNetworkRequest req;
req.setUrl("http://...");
mPage->mainFrame()->load(req, QNetworkAccessManager::GetOperation);
The first time the above code runs mPage=0, the page loads fine, and everything else goes as expected. The second time, it's a pointer to the previously created page, so it gets disconnected and deleted. After load() returns control to the main event loop, I get a SIGSEGV with the following stack trace.
#0 0x00007ffff49a1e56 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtCore.so.4
#1 0x00007ffff6842972 in QWebFrame::loadFinished(bool) () from /home/ubuntu/3rdparty/qt- 4.8.1/lib/libQtWebKit.so.4
#2 0x00007ffff6881955 in ?? () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtWebKit.so.4
#3 0x00007ffff6bde3ab in ?? () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtWebKit.so.4
#4 0x00007ffff6c0ef14 in ?? () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtWebKit.so.4
#5 0x00007ffff6e0183b in ?? () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtWebKit.so.4
#6 0x00007ffff6e016e8 in ?? () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtWebKit.so.4
#7 0x00007ffff6e01755 in ?? () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtWebKit.so.4
#8 0x00007ffff6e0218c in ?? () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtWebKit.so.4
#9 0x00007ffff49a20c1 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtCore.so.4
#10 0x00007ffff4d72b46 in ?? () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtNetwork.so.4
#11 0x00007ffff4de91c5 in ?? () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtNetwork.so.4
#12 0x00007ffff49a7286 in QObject::event(QEvent*) () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtCore.so.4
#13 0x00007ffff5243fa4 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtGui.so.4
#14 0x00007ffff5248e23 in QApplication::notify(QObject*, QEvent*) () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtGui.so.4
#15 0x00007ffff498e21c in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtCore.so.4
#16 0x00007ffff4991aba in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtCore.so.4
#17 0x00007ffff49bce53 in ?? () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtCore.so.4
#18 0x00007ffff235ba5d in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#19 0x00007ffff235c258 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#20 0x00007ffff235c429 in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#21 0x00007ffff49bd27f in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtCore.so.4
#22 0x00007ffff52e78ae in ?? () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtGui.so.4
#23 0x00007ffff498d002 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtCore.so.4
#24 0x00007ffff498d257 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from / home/ubuntu/3rdparty/qt-4.8.1/lib/libQtCore.so.4
#25 0x00007ffff4991db5 in QCoreApplication::exec() () from /home/ubuntu/3rdparty/qt-4.8.1/lib/libQtCore.so.4
#26 0x0000000000408ba0 in main (argc=3, argv=<optimized out>) at RenderTreeAnalyzer.cpp:474
You have to schedule mPage for deletion with deleteLater rather than deleting it directly because there may well be undelivered events for your mPage in the event queue.
If control returns to the event loop, Qt tries to access the deleted object which leads to your segmentation fault.
However, from you code example, I did not fully understand why you need the newPage() signal.
From my understanding, mPage->deleteLater() should be sufficient (w.r.t. to avoiding the seg-fault) and you should be able to reassign your local/member variable mPage with a new value (i.e. a pointer to a new Page) immediately.
If you need the old Page to be deleted immediately, it is correct that you need to return to the event loop, because it is only deleted then.
You have several opportunities to trigger the event loop and get you deletion request processed:
Use your queued signal/slot setup
Call QApplication::processEvents(); after calling mPage->deleteLater() to process any events in the event queue.
Call QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); to only process all deferred deletions.
Call QCoreApplication::sendPostedEvents(mPage, QEvent::DeferredDelete); to only process the deferred deletion for mPage.
Disclaimer: I have not explicitly tried these suggesions (at least not recently that I remember), but I checked a lot of Qt's event management source code recently (in addition to the docs, of course), so I am pretty confident that all of them work.
The issue was delete mPage;. I have to use mPage->deleteLater(); emit getNext(); instead. deleteLater() schedules the object for deletion the next time the program returns to the main event loop. emit getNext(); is connected to a slot that picks back up at mPage = new Page();. Its connection type is Qt::QueuedConnection, so it will yield to the event loop before calling the slot. I'm not exactly sure why, but you have to schedule the deletion and return to the event loop like this to properly close the old signals and set up the new ones.
So, this works, but if someone can tell me what's going on in more detail, I'll accept yours instead. Thanks.
I have a piece of code looking like this :
TAxis *axis = 0;
if (dynamic_cast<MonitorObjectH1C*>(obj))
axis = (dynamic_cast<MonitorObjectH1C*>(obj))->GetXaxis();
Sometimes it crashes :
Thread 1 (Thread -1208658240 (LWP 11400)):
#0 0x0019e7a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
#1 0x048c67fb in __waitpid_nocancel () from /lib/tls/libc.so.6
#2 0x04870649 in do_system () from /lib/tls/libc.so.6
#3 0x048709c1 in system () from /lib/tls/libc.so.6
#4 0x001848bd in system () from /lib/tls/libpthread.so.0
#5 0x0117a5bb in TUnixSystem::Exec () from /opt/root/lib/libCore.so.5.21
#6 0x01180045 in TUnixSystem::StackTrace () from /opt/root/lib/libCore.so.5.21
#7 0x0117cc8a in TUnixSystem::DispatchSignals ()
from /opt/root/lib/libCore.so.5.21
#8 0x0117cd18 in SigHandler () from /opt/root/lib/libCore.so.5.21
#9 0x0117bf5d in sighandler () from /opt/root/lib/libCore.so.5.21
#10 <signal handler called>
#11 0x0533ddf4 in __dynamic_cast () from /usr/lib/libstdc++.so.6
I have no clue why it crashes. obj is not null (and if it was it would not be a problem, would it ?).
What could be the reason for a dynamic cast to crash ?
If it can't cast, it should just return NULL no ?
Some possible reasons for the crash:
obj points to an object with a non-polymorphic type (a class or struct with no virtual methods, or a fundamental type).
obj points to an object that has been freed.
obj points to unmapped memory, or memory that has been mapped in such a way as to generate an exception when accessed (such as a guard page or inaccessible page).
obj points to an object with a polymorphic type, but that type was defined in an external library that was compiled with RTTI disabled.
Not all of these problems necessarily cause a crash in all situations.
I suggest using a different syntax for this code snippet.
if (MonitorObjectH1C* monitorObject = dynamic_cast<MonitorObjectH1C*>(obj))
{
axis = monitorObject->GetXaxis();
}
You can still crash if some other thread is deleting what monitorObject points to or if obj is crazy garbage, but at least your problem isn't casting related anymore and you're not doing the dynamic_cast twice.
As it crashes only sometimes, i bet it's a threading issue. Check all references to 'obj':
grep -R 'obj.*=' .
dynamic_cast will return 0 if the cast fails and you are casting to a pointer, which is your case. The problem is that you have either corrupted the heap earlier in your code, or rtti wasn't enabled.
Are you sure that the value of 'obj' has been correctly defined?
If for example it is uninitialised (ie random) them I could see it causing a crash.
Can the value of obj be changed by a different thread?