Trouble diagnosing segfault in Qt application - c++

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.

Related

Is gettimeofday async signal safe ? and can it cause deadlock if used in signal handler?

Previously I had asked a question regarding how to terminate thread blocked for I/O. I have used pthread_kill() instead of pthread_cancel() or writing to pipes, considering few advantages. After implementing the code to send signal (SIGUSR2) to the target thread using pthread_kill(), initially it worked fine and didn't face any issues.
static void signalHandler(int signum) {
LogInfo("SIGNAL HANDLER : %d",signum); //print info message using logger utility
}
void setSignalHandler() {
struct sigaction actions;
memset(&actions, 0, sizeof(actions));
sigemptyset(&actions.sa_mask);
actions.sa_flags = 0;
actions.sa_handler = signalHandler;
int rc = sigaction(SIGUSR2,&actions,NULL);
if(rc < 0) {
LogError("Error in sigaction"); //print error using logger utility
}
}
void stopThread() {
fStop = 1; //set the flag to stop the thread
if( ftid ) { //ftid is pthread_t variable of thread that needs to be terminated.
LogInfo("Before pthread_kill()");
int kill_result = pthread_kill(ftid,SIGUSR2); // send signal to interrupt the thread if blocked for poll() I/O
LogInfo("pthread_kill() returned : %d ( %s )",kill_result,strerror(kill_result));
int result = pthread_join( ftid, NULL );
LogInfo("Event loop stopped for %s", fStreamName);
LogInfo( "pthread_join() -> %d ( %s )\n", result, strerror(result) );
if( result == 0 ) ftid = 0;
}
}
Recently I have noticed a deadlock issue where few threads (which tried to log statements) blocked with below stacktrace
#0 0x00007fc1b2dc565c in __lll_lock_wait_private () from /lib64/libc.so.6
#1 0x00007fc1b2d70f0c in _L_lock_2462 () from /lib64/libc.so.6
#2 0x00007fc1b2d70d47 in __tz_convert () from /lib64/libc.so.6
#3 0x00000000004708f7 in Logger::getCurrentTimestamp(char*) ()
getCurrentTimestamp(char*) function is called from our logger module when LogInfo() or LogError() functions are invoked. This function internally calls gettimeofday() to print the current time in logs. So I'm suspecting LogInfo() function (which calls gettimeofday()) called inside signalHandler() might be causing the deadlock issue. But i'm not confident of this as this issue is not getting reproduced frequently and i did not get any information stating that gettimeofday() is not async signal safe.
gettimeofday() is thread safe and i'm considering it's not async signal safe as it was not listed under async signal safe functions.
1) Can I consider gettimeofday() is not async signal safe and it was the root cause of deadlock ?
2) Are there any known issues where use of pthread_kill() might cause deadlock ?
EDIT :
Below is the definition of getCurrentTimeStamp() function
char* Logger::getCurrentTimestamp ( char *tm_buff ) {
char curr_time[ 32 ] = { 0 };
time_t current = time( NULL );
struct timeval detail_time;
if ( tm_buff ) {
strftime( curr_time, sizeof(curr_time), "%Y-%m-%d-%H:%M:%S", localtime( &current ) );
gettimeofday( &detail_time, NULL );
sprintf( tm_buff, "%s:%03d", curr_time, (int) (detail_time.tv_usec / 1000) );
return (tm_buff);
}
return (NULL);
}
stack trace of the thread that was interrupted by signal.
#0 0x00007fc1b2dc565c in __lll_lock_wait_private () from /lib64/libc.so.6
#1 0x00007fc1b2d70f0c in _L_lock_2462 () from /lib64/libc.so.6
#2 0x00007fc1b2d70d47 in __tz_convert () from /lib64/libc.so.6
#3 0x00000000004708f7 in Logger::getCurrentTimestamp(char*) ()
#4 0x000000000046e80f in Log::write(Logger*, LogType, std::string const&, char const*) ()
#5 0x000000000046df74 in Log::i(Logger*, char const*, std::string const&, std::string const&, char const*, ...) ()
#6 0x0000000000456b67 in ?? ()
#7 <signal handler called>
#8 0x00007fc1b2da8dc5 in _xstat () from /lib64/libc.so.6
#9 0x00007fc1b2d71056 in __tzfile_read () from /lib64/libc.so.6
#10 0x00007fc1b2d703b4 in tzset_internal () from /lib64/libc.so.6
#11 0x00007fc1b2d70d63 in __tz_convert () from /lib64/libc.so.6
#12 0x00000000004708f7 in Logger::getCurrentTimestamp(char*) ()
#13 0x000000000047030e in Logger::writeLog(int, std::string&, std::string&) ()
#14 0x0000000000470633 in Logger::Write(Logger*, int, std::string, std::string const&) ()
#15 0x000000000046eb02 in Log::write(Logger*, LogType, std::string const&, char const*) ()
#16 0x000000000046df74 in Log::i(Logger*, char const*, std::string const&, std::string const&, char const*, ...) ()
gettimeofday itself is not signal safe, as you already found out.
However, "POSIX.1-2008 marks gettimeofday() as obsolete, recommending the use of clock_gettime(2) instead."(source) and clock_gettime is signal-safe (and also thread-safe), so that might be an alternative for you.
gettimeofday is not defined as async-signal-safe, but if you pass 0 for the second (timezone) argument, it doesn't have to do anything that time and clock_gettime (both of which are officially async-signal-safe) don't also do, so as a matter of QoI it should be async-signal-safe in that case.
Your deadlock is inside the internal libc function __tz_convert.
#2 0x00007fc1b2d70d47 in __tz_convert () from /lib64/libc.so.6
#3 0x00000000004708f7 in Logger::getCurrentTimestamp(char*) ()
It appears to have been called directly from Logger::getCurrentTimestamp, but that's because it was "tail called" from a documented API function. There are only four functions in GNU libc that call __tz_convert (I grepped the source code): localtime, localtime_r, gmtime, and gmtime_r. Therefore, your problem is not that you are calling gettimeofday, but that you are calling one of those functions.
localtime and gmtime are obviously not async-signal-safe since they write to a global variable. localtime_r and gmtime_r are not async-signal-safe either, because they have to look at the global database of timezone information (yes, even gmtime_r does this — it might be possible to change it not to need to do that, but it still wouldn't be a thing you could rely on cross-platform).
I don't think there's a good workaround. Formatted output from an async signal handler is going to trip over all kinds of other problems; my advice is to restructure your code so that you never need to call logging functions from async signal handlers.

Why the destrcution is called twice?

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.

QSerialPort::readAll() leads to SIGSEGV / SIGABRT if called in a while-loop

I'm communicating with a hardware device using QSerialPort. New data does not emit the "readyRead"-Signal, so I decided to write a read thread using QThread.
This is the code:
void ReadThread::run()
{
while(true){
readData();
if (buffer.size() > 0) parseData();
}
}
and
void ReadThread::readData()
{
buffer.append(device->readAll();
}
with buffer being an private QByteArray and device being a pointer to the QSerialPort. ParseData will parse the data and emit some signals. Buffer is cleared when parseData is left.
This works, however after some time (sometimes 10 seconds, sometimes 1 hour) the program crashes with SIGSEGV with the following trace:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff3498700 (LWP 24870)]
malloc_consolidate (av=av#entry=0x7fffec000020) at malloc.c:4151
(gdb) bt
#0 malloc_consolidate (av=av#entry=0x7fffec000020) at malloc.c:4151
#1 0x00007ffff62c2ee8 in _int_malloc (av=av#entry=0x7fffec000020, bytes=bytes#entry=32769) at malloc.c:3423
#2 0x00007ffff62c4661 in _int_realloc (av=av#entry=0x7fffec000020, oldp=oldp#entry=0x7fffec0013b0, oldsize=oldsize#entry=64, nb=nb#entry=32784) at malloc.c:4286
#3 0x00007ffff62c57b9 in __GI___libc_realloc (oldmem=0x7fffec0013c0, bytes=32768) at malloc.c:3029
#4 0x00007ffff70d1cdd in QByteArray::reallocData(unsigned int, QFlags<QArrayData::AllocationOption>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#5 0x00007ffff70d1f07 in QByteArray::resize(int) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#6 0x00007ffff799f9fc in free (bytes=<optimized out>, this=0x609458)
at ../../include/QtSerialPort/5.3.2/QtSerialPort/private/../../../../../src/serialport/qt4support/include/private/qringbuffer_p.h:140
#7 read (maxLength=<optimized out>, data=<optimized out>, this=0x609458)
at ../../include/QtSerialPort/5.3.2/QtSerialPort/private/../../../../../src/serialport/qt4support/include/private/qringbuffer_p.h:326
#8 QSerialPort::readData (this=<optimized out>, data=<optimized out>, maxSize=<optimized out>) at qserialport.cpp:1341
#9 0x00007ffff722bdf0 in QIODevice::read(char*, long long) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#10 0x00007ffff722cbaf in QIODevice::readAll() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#11 0x00007ffff7bd0741 in readThread::readData (this=0x6066c0) at ../reader.cpp:212
#12 0x00007ffff7bc80d0 in readThread::run (this=0x6066c0) at ../reader.cpp:16
#13 0x00007ffff70cdd2e in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#14 0x00007ffff6e1c0a4 in start_thread (arg=0x7ffff3498700) at pthread_create.c:309
#15 0x00007ffff632f04d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
I'm not sure how to reproduce the problem correctly, since it appears randomly. If I comment out the "readData()" in my while loop, the crashes do not appear anymore (of course no data can be parsed, then).
Does anyone have a clue what this could be?
What is the buffer? Could it be, another thread is reading the data from the buffer and clears it afterwards?
Try to lock it (and all other data shared between threads) e.g. with a mutex
QMutex mx; // could be also member of the ReadThread class
void ReadThread::readData()
{
mx.lock();
buffer.append(device->readAll();
mx.unlock();
}
And do the same in the code which reads and clears the buffer from another thread (I'm not doing the assumption, that this is parseData())
Another possibility could be, parseData() calls some code running in GUI-Thread. This doesn't work in Qt4 and probably also in Qt5
You're using the instance of a QObject from multiple threads at once. This generally speaking leads to undefined behavior, as you've just seen. QSerialPort will work just fine on the GUI thread. Only once you get it to work there, you can move it to a worker thread.
Note that if the event loop (app.exec() call in main() or QThread::run()) isn't executing, the signals won't be happening. It looks as if you tried to write pseudo synchronous code and have (predictably) failed. Don't do that.
Something like this is supposed to work:
#include <QtCore>
#include <QtSerialPort>
int main(int argc, char ** argv) {
QCoreApplication app(argc, argv);
QSerialPort port;
port.setPortName(...);
port.setBaudRate(...);
... // etc
if (! port.open(QIODevice::ReadWrite)) {
qWarning() << "can't open the port";
return 1;
}
... // set the port
connect(&port, &QIODevice::readyRead, [&]{
qDebug() << "got" << port.readAll().size() << "bytes";
});
return app.exec(); // the signals will be emitted from here
}
Ensure that all serial port related objects are initialized and used only in the separate thread. Send received data or parsed events to the UI thread by using signal/slot-mechanism.
Note also that if you inherit QThread in readThread, the constructor may be executed in the UI thread and other functions in the readThread. In that case, start the readThread and run separate initialization function before other functions (for example, by sending proper signal from the UI thread).

Munmap_chunk() error, cannot understand pointer behavior

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.

Strange behaviour with std::unique_ptr and std::ostringstream (SIGSEGV)

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);