I am writing an application that uses pion library and notice a crash when I try to send a request. The crash is happening due to segmentation fault. This is in Linux and I am linking with PION_FULL.
Code:
pion::net::HTTPRequest httpRequest("/sm_login/trusted.asp?app-id=test");
int port = 80;
httpRequest.setMethod("GET");
httpRequest.addHeader("Host", "127.0.0.1");
pion::net::TCPConnection connPtr(IO_service);
error = connPtr.connect(boost::asio::ip::address::from_string("127.0.0.1"), port);
if (error || !connPtr.is_open())
{
dprintf(("Unable to establish connection"));
return false;
}
httpRequest.send(connPtr, error);
Dump:
#0 0x0eec4bb4 in void pion::net::HTTPMessage::changeValue<std::tr1::unordered_multimap<std::string, std::string, CaseInsensitiveHash, CaseInsensitiveEqual, std::allocator<std::pair<std::string const, std::string> > >
>(std::tr1::unordered_multimap<std::string, std::string, CaseInsensitiveHash, CaseInsensitiveEqual, std::allocator<std::pair<std::string const, std::string> > >&, std::string const&, std::string const&) () from /sw/lib/libpion-net-2.2.12.so
#1 0x0eec11f0 in pion::net::HTTPMessage::send(pion::net::TCPConnection&, boost::system::error_code&) () from /sw/lib/libpion-net-2.2.12.so
#2 0x0f1e6c24 in CHeapInterface::SendRequest(std::string const&, std::string&, CHeapInterface::EHeapMsgType) () from /sw/lib/libMgmt.so
Thanks,
The problem was due to mismatch in cross compiler version used to build pion libs. The application is not crashing anymore.
Related
I am using a library (C++ REST SDK) in which I can set a handler for a specific event. Precisely I set a close handler which gets called when a websocket connection gets closed by the client(me) or the server. The handler is set like this:
// WebsocketClient is my own custom class
// m_pclClient holds the connection (of type websocket_callback_client)
std::function<void(web::websockets::client::websocket_close_status close_status, const utility::string_t &reason, const std::error_code &error)> handler(std::bind(&WebsocketClient::close_handler, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
this->m_pclClient->set_close_handler(handler);
When I now close the connection the library handles the closing procedure and, after finishing the process, calls handler with its three parameters.
When closing the connection an error occurs. I am not sure if it's a bug inside the library or my mistake. gdb output when closing the connection:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffe1c23700 (LWP 13849)]
0x00000000004e20b7 in std::__invoke_impl<void, void (WebsocketClient::* const&)(web::websockets::client::websocket_close_status, std::string const&, std::error_code const&), WebsocketClient*&, web::websockets::client::websocket_close_status, std::string const&, std::error_code const&>(std::__invoke_memfun_deref, void (WebsocketClient::* const&)(web::websockets::client::websocket_close_status, std::string const&, std::error_code const&), WebsocketClient*&, web::websockets::client::websocket_close_status&&, std::string const&, std::error_code const&) (__f=
#0x80d290: (void (WebsocketClient::*)(WebsocketClient * const, web::websockets::client::websocket_close_status, const std::basic_string<char, std::char_traits<char>, std::allocator<char> > &, const std::error_code &)) 0x4cf120 <WebsocketClient::close_handler(web::websockets::client::websocket_close_status, std::string const&, std::error_code const&)>, __t=#0x80d2a0: 0x8081f8,
__args#0=<unknown type in /path/to/executable, CU 0x1d28f4, DIE 0x21f672>, __args#1="TLS Short Read", __args#2=...) at /usr/include/c++/6/functional:235
235 return ((*std::forward<_Tp>(__t)).*__f)(std::forward<_Args>(__args)...);
There's obviously a problem with argument #0: web::websockets::client::websocket_close_status close_status.
It seems that when the handler should be invoked, the type of the first argument is unknown. See in the gdb output: "__args#0= < unknown type in /path/to/executable"
Why is this happening and how to fix it?
I'm making a NodeJS addon using the Nan library, and I'm running into an issue where calling a callback (created on the javascript side and passed to the addon to be executed asyncronously) will cause a segfault - but only about once every 10 thousand or so runs.
There's quite a bit of complexity involved in how everything operates, but I'm hoping that someone will see something I missed or be able to figure out what's going on.
The C++ callback function is created from the javascript callback like this:
auto nodeFunc = val.As<v8::Function>();
auto nodeCb = std::make_shared<Nan::Callback>(nodeFunc);
auto callback = [nodeCb] (std::string err, std::string val) -> void {
Nan::HandleScope scope;
v8::Local<v8::Value> argv[2];
if (err.length() == 0) {
auto isolate = v8::Isolate::GetCurrent();
auto json = v8::JSON::Parse(isolate, Nan::New(val).ToLocalChecked());
auto object = json.ToLocalChecked();
argv[0] = Nan::Null();
argv[1] = object;
} else {
argv[0] = Nan::Error(err.c_str());
argv[1] = Nan::Null();
}
try {
nodeCb->Call(2, argv);
} catch (std::exception& ex) {
std::cout << ex.what() << std::endl;
Nan::ThrowReferenceError(ex.what());
}
};
After creation, it is passed to a separate thread which eventually sends the callback to the main libuv thread using uv_async_send() and executes it. This works fine the vast majority of the time, but will very rarely segfault on the nodeCb->Call(2, argv) line.
If anyone has any insight into what's happening here, I'd really appreciate it.
Also, here's the call stack from gdb in case that's any help:
#0 0x00000000009870e0 in v8::Function::Call(v8::Local<v8::Value>, int, v8::Local<v8::Value>*) ()
#1 0x00000000010a562c in node::MakeCallback(node::Environment*, v8::Local<v8::Value>, v8::Local<v8::Function>, int, v8::Local<v8::Value>*) ()
#2 0x00000000010a5a98 in node::MakeCallback(v8::Isolate*, v8::Local<v8::Object>, v8::Local<v8::Function>, int, v8::Local<v8::Value>*) ()
#3 0x00007ffff47b4b30 in Nan::Callback::Call_ (this=0x20c3500, isolate=0x1ded750, target=..., argc=2,
argv=0x7fffffffa430) at ../node_modules/nan/nan.h:1477
#4 0x00007ffff47b4a93 in Nan::Callback::Call (this=0x20c3500, argc=2, argv=0x7fffffffa430)
at ../node_modules/nan/nan.h:1443
#5 0x00007ffff47b194b in detail::info::__lambda1::operator() (__closure=0x1e40710, err="",
val="{\"index\":1,\"status\":1}") at ../node/utils.hpp:125
#6 0x00007ffff47b37f2 in std::_Function_handler<void(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >), detail::info::setElementValue(T&, v8::Local<v8::Value>, size_t) [with T = std::function<void(std::basic_string<char>, std::basic_string<char>)>; size_t = long unsigned int]::__lambda1>::_M_invoke(const std::_Any_data &, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >) (__functor=..., __args#0="", __args#1="")
at /usr/include/c++/4.8.2/functional:2071
#7 0x00007ffff44cd339 in std::function<void (std::string, std::string)>::operator()(std::string, std::string) const (this=0x1e29c80, __args#0="", __args#1="")
at /opt/rh/devtoolset-4/root/usr/include/c++/5.2.1/functional:2271
#8 0x00007ffff44e172c in std::_Bind<std::function<void (std::string, std::string)> (char const*, std::string)>::__call<void, , 0ul, 1ul>(std::tuple<>&&, std::_Index_tuple<0ul, 1ul>) (this=0x1e29c80,
__args=<unknown type in /usr/local/lib/libSCPlay.so, CU 0x0, DIE 0x83e21>)
at /opt/rh/devtoolset-4/root/usr/include/c++/5.2.1/functional:1074
#9 0x00007ffff44daec8 in std::_Bind<std::function<void (std::string, std::string)> (char const*, std::string)>::operator()<, void>() (this=0x1e29c80)
at /opt/rh/devtoolset-4/root/usr/include/c++/5.2.1/functional:1133
#10 0x00007ffff44d3b58 in std::_Function_handler<void (), std::_Bind<std::function<void (std::string, std::string)> (char const*, std::string)> >::_M_invoke(std::_Any_data const&) (__functor=...)
at /opt/rh/devtoolset-4/root/usr/include/c++/5.2.1/functional:1871
#11 0x00007ffff44fab0a in std::function<void ()>::operator()() const (this=0x7fffffffa650)
at /opt/rh/devtoolset-4/root/usr/include/c++/5.2.1/functional:2271
#12 0x00007ffff44f890c in DeviceThread::asyncListener (handle=0x1efb9f0)
at /home/scl37510/Projects/SCPlay2/lib/device_thread.cpp:124
#13 0x0000000001316b0b in uv__async_event (loop=0x1de7fe0 <default_loop_struct>, w=<optimized out>,
nevents=<optimized out>) at ../deps/uv/src/unix/async.c:98
#14 0x0000000001316be3 in uv__async_io (loop=0x1de7fe0 <default_loop_struct>,
w=0x1de81a8 <default_loop_struct+456>, events=<optimized out>) at ../deps/uv/src/unix/async.c:138
#15 0x00000000013271b0 in uv__io_poll (loop=loop#entry=0x1de7fe0 <default_loop_struct>, timeout=0)
at ../deps/uv/src/unix/linux-core.c:380
#16 0x00000000013176c6 in uv_run (loop=0x1de7fe0 <default_loop_struct>, mode=UV_RUN_ONCE)
at ../deps/uv/src/unix/core.c:354
#17 0x00000000010aabe0 in node::Start(int, char**) ()
#18 0x00007ffff6bf5b35 in __libc_start_main () from /lib64/libc.so.6
#19 0x00000000007b1f1d in _start ()
Edit: I've created a much smaller test program to see if I could pinpoint the source of the bug, and I've discovered that I can prevent it by changing the Callback shared_ptr to a regular pointer, deleting it immediately after the nodeCb->Call(2,argv) line.
Is there some semantic difference between the two that could cause this?
The usage of shared_ptr to wrap a Callback is suspicious:
std::make_shared<Nan::Callback>(nodeFunc);
I don't think V8 would like references being handled that way.
Nan::Callback itself contains a Persistent that it uses to store the function's value, so you need not worry about persistence.
...I just noticed your edit after I already wrote out this answer. The shared_ptr is potentially dangerous to mix with V8 internal handles and references.
If your intention is to store the callback and delete it immediately, maybe you could benefit by refactoring your code to use Nan::AsyncWorker instead.
I have this simple code:
#include <boost/unordered_set.hpp>
int main (int argc, char* argv[])
{
boost::unordered_set<int> bset;
for (int i=0; i<10000; i++) {
bset.insert(i);
}
return 0;
}
When I create a purify build and run, I am getting the following UMR (uninitialized memory read) error. I could not figure out how to get rid of this.
**** Purify instrumented app_pure (pid 21943) ****
UMR: Uninitialized memory read (10000 times):
This is occurring while in thread 21943:
std::pair>, bool > boost::unordered::detail::table_impl, int, boost::hash, std::equal_to >>::emplace_impl>(int const&, boost::unordered::detail::set, int, boost::hash, std::equal_to > const&) [unique.hpp:414]
std::pair>, bool > boost::unordered::detail::table_impl, int, boost::hash, std::equal_to >>::emplace(boost::unordered::detail::emplace_args1, int, boost::hash, std::equal_to >> const&) [unique.hpp:393]
std::pair, boost::unordered::detail::ptr_node const* >, bool > boost::unordered::unordered_set, std::equal_to, std::allocator >::emplace(int const&) [unordered_set.hpp:277]
boost::unordered::unordered_set, std::equal_to, std::allocator >::insert(int const&) [unordered_set.hpp:380]
main [app.cxx:8]
__libc_start_main [libc.so.6]
_start [crt1.o]
Reading 8 bytes from 0x7fffffffd668 on the stack of thread 21943 (7 bytes at 0x7fffffffd669 uninit).
Address 0x7fffffffd668 is 56 bytes past start of local variable "pos" in function std::pair>, bool > boost::unordered::detail::table_impl, int, boost::hash, std::equal_to >>::emplace_impl>(int const&, boost::unordered::detail::set, int, boost::hash, std::equal_to > const&).
My boost version is 1.54.0
My GCC version is 4.8.3
Purify version is 7.3 (Purify 7.3-mod1 150930 Linux (64-bit))
Can anyone please give any hint on how to solve this?
Thanks
When built with the latest XCode 5.1, iOS SDK 7.1 and LLVM 5.1, using libstdc++ for the C++ standard library, get crash in the std::string append method only on iOS 5.1 device.
Here's code example:
class TestClass
{
public:
TestClass()
{
m_string = "string1";
}
void AppendString()
{
m_string += std::string("string2");
std::string newString2 = m_string + "string3";
}
private:
string m_string;
};
App crashes in AppendString() method on this line:
std::string newString2 = m_string + "string3";
If I remove this line m_string += std::string("string2"); before creating newString2, code works fine.
Here's the stacktrace of crash:
#0 0x34c99fe8 in memcpy$VARIANT$CortexA8 ()
#1 0x3706f95a in std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) ()
#2 0x3706fbfa in std::string::reserve(unsigned long) ()
#3 0x3706fdb0 in std::string::append(char const*, unsigned long) ()
#4 0x000c0e5a in std::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) [inlined] at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/c++/4.2.1/bits/basic_string.h:2121
#5 0x000c0e3c in TestClass::AppendString() at /Users/sergei/Documents/2_3/House of Fun/cpp/CasinoSceneManager.cpp:122
Have anybody experinced same crash? It happens only on devices with iOS 5.1 and 5.1.1 and only if app was compiled with release flag, not debug.
Thank you for the help.
One more note.
If I change Optimization level to None [-O0] in Code Generation section in project settings, everything works fine.
Maybe the problem has some connection to code optimization.
Apple released a new GM seed for Xcode 5.1.1. In the release notes they say they fixed a couple crashes:
Fixed a compiled code crash on when targeting iOS 5.1.1. (16485980)!
Fixed a compiled code crash when using ARC and C++. (16368824)
http://adcdownload.apple.com//Developer_Tools/xcode_5.1.1_gm_seed/release_notes_xcode_5.1.1_gm_seed.pdf
I tried to overload QDebug::operator<< for std::string. I know that we can debug (using qDebug()) std::string objects using its std::string::c_str() function but I want to avoid typing .c_str each time.
Here is my attempt
#include <QDebug>
#include <string>
inline const QDebug& operator<< (const QDebug& qDebugObj, const std::string& str) {
return qDebugObj << str.c_str();
}
int main()
{
std::string s = "4444555";
qDebug() << s;
}
This program produces segmentation fault. What is incorrect with this code?
Here is the stack:
#1 0x00000037c407a911 in malloc () from /lib64/libc.so.6
#2 0x00000037ca8bd09d in operator new(unsigned long) () from /usr/lib64/libstdc++.so.6
#3 0x00000037ca89c3c9 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) ()
from /usr/lib64/libstdc++.so.6
#4 0x00000037ca89cde5 in ?? () from /usr/lib64/libstdc++.so.6
#5 0x00000037ca89cf33 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) () from /usr/lib64/libstdc++.so.6
#6 0x00000000004012ca in operator<< (qDebugObj=..., str="4444555") at main.cpp:5
If you look at every overloaded output operator, you will see that none have a const qualifier. Which is your problem, you try to modify a constant object. Remove the const qualification of the qDebugObject and the return value.
You should have compiler warnings screaming about it, and if not then you need to enable more warnings (at least use -Wall when compiling with GCC/clang).
The actual problem, as answered by Mike Seymour in a comment, is that your overload will be called recursively until you get a stack overflow.
A way of bypassing that might be to convert the string to something else, like for example a QString:
return qDebugObj << QString::fromStdString(str);
In addition to your attempt to make an output stream const, you also failed to follow the instructions in the QT documentation
// with the fixed output operator
inline QDebug operator<<(QDebug dbg, const std::string& str)
{
dbg.nospace() << QString::fromStdString(str);
return dbg.space();
}
QT wants the output operator passed by copy (not by reference). There used to be a reason for that, but I cannot remember what it was.