Boost asio crashes - crash

I have a program using cpprestsdk for http querying and websocketpp for subscribing a data stream. The program will crash immediately(it says Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)). But if I comment either of the http querying or subcribing data stream, the program won't crash.
#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>
#include "json.hpp"
#include <iostream>
#include <ctime>
#include <iostream>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <vector>
#include <string>
using std::string;
using namespace web;
using std::cout, std::endl;
using std::vector;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
typedef websocketpp::client<websocketpp::config::asio_tls_client> client;
typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
void on_stream_data(websocketpp::connection_hdl hdl, message_ptr msg) {
}
class OrderBook {
public:
void initialize() {
web::http::client::http_client_config cfg;
std::string uri = string("https://fapi.binance.com/fapi/v1/depth?symbol=btcusdt&limit=1000");
web::http::client::http_client client(U(uri), cfg);
web::http::http_request request(web::http::methods::GET);
request.headers().add("Content-Type", "application/x-www-form-urlencoded");
web::http::http_response response = client.request(request).get();
}
int start_stream() {
client c;
std::string uri = string("wss://fstream.binance.com/ws/btcusdt#depth#100ms");
try {
c.set_access_channels(websocketpp::log::alevel::all);
c.clear_access_channels(websocketpp::log::alevel::frame_payload);
c.init_asio();
c.set_message_handler(bind(on_stream_data, ::_1, ::_2));
websocketpp::lib::error_code ec;
client::connection_ptr con = c.get_connection(uri, ec);
if (ec) {
std::cout << "could not create connection because: " << ec.message() << std::endl;
return 0;
}
c.connect(con);
c.run();
} catch (websocketpp::exception const &e) {
std::cout << e.what() << std::endl;
}
}
};
int main(int argc, char *argv[]) {
OrderBook ob;
ob.initialize(); // comment either of these two lines, the program won't crash, otherwise the program will crash once start
std::this_thread::sleep_for(std::chrono::milliseconds(10000000));
ob.start_stream(); // comment either of these two lines, the program won't crash, otherwise the program will crash once start
}
When I run this program in Clion debug mode, Clion show that the crash comes from function in /opt/homebrew/Cellar/boost/1.76.0/include/boost/asio/ssl/detail/impl/engine.ipp
int engine::do_connect(void*, std::size_t)
{
return ::SSL_connect(ssl_);
}
It says Exception: EXC_BAD_ACCESS (code=1, address=0xf000000000)
What's wrong with it? is it because I run two pieces of code using boost::asio, and something shouldn't be initialized twice?

I can compile this and run it fine.
My best bet is that you might be mixing versions, particularly boost versions. A common mode of failure is caused when ODR violations lead to Undefined Behaviour.
Note that these header-only libraries depend on a number of boost libraries that are not header-only (e.g. Boost System, Thread and/or Chrono). You need to compile against the same version as the libraries you link.
If you use distribution packaged versions of any library (cpprestsdk, websocketpp or whatever json library that is you're using) then you'd be safest also using the distribution packaged version of Boost.
I'd personally simplify the situation by just using Boost (Beast for HTTP/websocket, Json for, you guessed it).
Running it all on a test Ubuntu 18.04 the OS Boost 1.65 version, the start_stream sequence triggers this informative error:
[2022-05-22 13:42:11] [fatal] Required tls_init handler not present.
could not create connection because: Connection creation attempt failed
While being UBSAN/ASAN clean. Perhaps that error helps you, once you figure out the configuration problems that made your program crash.

Related

Linking an unknown dll

I've got this dll (called unknown.dll) from which i only know what Ghidra told me. I'm using LoadLibraryW to load it, but (in x86) it throws me the error 126. However, in 64x it gives me the error 193, so i don't think that the problem is that my program can't find my dll...
Here is my code :
#include <iostream>
#include <Windows.h>
typedef int(__cdecl* FunctionIWant)();
int main()
{
HMODULE hmod = LoadLibraryW(L"C:\\unknown.dll");
if (hmod != NULL)
{
...
}
else
std::cout << GetLastError();
return 0;
}
What am I doing wrong ?
126 is ERROR_MOD_NOT_FOUND. Either your DLL can't be found, or more likely one if it's dependencies can't be found.
193 is ERROR_BAD_EXE_FORMAT. This is because you can't mix 32 and 64 bit DLLs.
The fact that you get ERROR_BAD_EXE_FORMAT when you run under 64 bit tells you that your DLL is found. Therefore we can conclude that its dependencies are not present.
Consult the documentation to discover what dependencies are required.

DLL import failure in using WinDivert

I am going to design a program using WinDivert to manipulate the network traffic.
The language I use is C++ and the program is designed under Visual Studio 2008.
Firstly I create a project in visual C++ CLR (Windows Forms Application) so I can implement the UI simply.
For importing the WinDirvert Library, I have done the following setting in project properties:
Configuaration Properties: General
Common Language Runtime support: Common Language Runtime Support(/ctr)
Configuaration Properties: Linker
Additional Dependencies: link of WinDivert.lib
Module Definition File: link of windivert.def
Within the project I have created, I also added the windivert.h in the header files.
Also, windivert.h is included in the main entry point of my project (ProjectG.cpp):
#include "stdafx.h"
#include "Form1.h"
#pragma managed(push, off)
#include "windivert.h"
#pragma managed(pop)
using namespace ProjectG;
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew Form1());
HANDLE handle;
unsigned char packet[8192];
UINT packet_len;
WINDIVERT_ADDRESS addr;
handle = WinDivertOpen("udp", WINDIVERT_LAYER_NETWORK, 0,
WINDIVERT_FLAG_DROP);
if (handle == INVALID_HANDLE_VALUE)
{
Application::Exit();
}
while (TRUE)
{
// Read a matching packet.
if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
{
MessageBox::Show("Fail");
continue;
}
}
return 0;
}
Finally, I put the {WinDivert.dll, windivert.h, WinDivert.lib, WinDivert32.sys} under the project directory.
However, the following error is shown:
fatal error LNK1306: DLL entry point "int __clrcall main(cli::array<class
System::String ^ >^)" (?main##$$HYMHP$01AP$AAVString#System###Z) cannot be managed;
compile to native ProjectG.obj ProjectG
Additional: (a warning)
warning LNK4070: /OUT:WinDivert.dll directive in .EXP differs from output filename
'C:\Users\David\Desktop\css\ProjectG\Debug\ProjectG.exe'; ignoring directive
ProjectG.exp ProjectG
Question:
How can I resolve this situation?
a) your main source is .cpp, so you can delete [STAThreadAttribute] and change
int main(array<System::String ^> ^args) to int _tmain(int argc, _TCHAR* argv[])
b) exclude windivert.def from linker Module Definition File, this only when you are creating a DLL
c) the DLL/SYS files would need to be copied to the Debug and Release folders

QGuiApplication & QXmlQuery problems on qt5

I'm trying to use QtXmlPatterns module in order to parse an XML file.
Unfortunately using Qt5.1 on MacOsX 10.7&10.8 I found a problem I have not with Qt4.8.5.
#include <QCoreApplication>
#include <QGuiApplication>
#include <QXmlQuery>
#include <QStringList>
#include <QDebug>
int main(int argc, char *argv[])
{
//QGuiApplication a(argc, argv);
QCoreApplication a(argc, argv);
QXmlQuery qry;
qry.setQuery("doc(\"file.xml\")");
QStringList lst;
qry.evaluateTo(&lst);
qDebug() << lst;
return 0;
}
this is the .pro I'm using.
QT += core gui xmlpatterns
TARGET = Test
TEMPLATE = app
CONFIG -= app_bundle
SOURCES += main.cpp
If I run a QCoreApplication everything works properly, instead if I switch on QGuiApplication (or a QApplication) this small program hangs forever on the evaluteTo function. It doesn't matter if file.xml exists or not.
On Windows and on Linux the same program run smoothly even if I use the QCoreApplication or the QGuiApplication or the QApplication.
I tried also to play a little with the QXmlQuery functions. If I call the setFocus function I got the same behaviour (with QCoreApplication everything it's ok, with QGuiApplication it hangs for ever on the setFocus function).
Suggestions?

How to make a loadable dll to use tcl code functionality by any program

I have created a GUI using tcl. I want to make some of the core functionalities of the tcl code available to be used by any program which supports dll. For that i have taken a very simple tcl code example, which adds two integer numbers and i have written a c wrapper function to use this functionality. This is working for me. Now how can i create a dll for these two c and tcl files, so that any program can use this addition functionality by simply loading the dll.
Here is my simple tcl code :
/* Filename : simple_addition.tcl */
#!/usr/bin/env tclsh8.5
proc add_two_nos { } {
set a 10
set b 20
set c [expr { $a + $b } ]
puts " c is $c ......."
}
And here is my c wrapper function which uses the above tcl addition functionality :
#include <tcl.h>
#include <tclDecls.h>
#include <tclPlatDecls.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char **argv) {
Tcl_Interp *interp;
int code;
char *result;
printf("inside main function \n");
Tcl_FindExecutable(argv[0]);
interp = Tcl_CreateInterp();
code = Tcl_Eval(interp, "source simple_addition.tcl; add_two_nos");
/* Retrieve the result... */
result = Tcl_GetString(Tcl_GetObjResult(interp));
/* Check for error! If an error, message is result. */
if (code == TCL_ERROR) {
fprintf(stderr, "ERROR in script: %s\n", result);
exit(1);
}
/* Print (normal) result if non-empty; we'll skip handling encodings for now */
if (strlen(result)) {
printf("%s\n", result);
}
/* Clean up */
Tcl_DeleteInterp(interp);
exit(0);
}
This c wrapper is working fine for me and gives correct results.
Now I want to create a dll file, so that if i include that dll to any program that supports dll, it should be able to use this addition functionality of the above tcl code. Can anybody please tell me the way i can do it. Please help me. I am new to this dll concept.
In order to create the .dll you'll have to use something like Visual Studio and C or C++ to create the .dll (there are lots of other tools out there that can create .dll files but VS is easy to get hold of and to use.) So in VS create a new project, this needs to be a C++ WIN32 project. Select the DLL application type and the Export Symbols additional option.
VS will create a basic .dll that you can then amend to do what you want. I short I'd look at putting the creating/destruction of the intrepter into the dllmain:
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
Tcl_FindExecutable(NULL);
interp = Tcl_CreateInterp();
}
case DLL_THREAD_ATTACH:
break ;
case DLL_THREAD_DETACH:
break ;
case DLL_PROCESS_DETACH:
{
Tcl_DeleteInterp(interp);
break;
}
}
return TRUE;
}
and then create functions exported by the .dll that make use of the interpreter. If you aren't familiar with the concept of shared libaries then I'd suggest spending a little time reading up on them, try here and here for some background reading.

About stl list::splice

I am facing a problem with splicing the list with itself. Note that I have gone through splice() on std::list and iterator invalidation
There the question was about two different lists. But my question is about the same list.
mylist.splice(mylist.end(), mylist, ++mylist.begin());
It seems that gcc 3.x is invalidating the moved iterator. So I suppose it is deallocating and allocating the node again. This does not make sense for the same list. SGI does tell that this version of splice should not invalidate any iterators. Is this a bug with gcc 3.x, if it is there any workaround?
In the mean time I was going through the stl_list.h file. But stuck with the transfer() function, I could not find a definition for these.
struct _List_node_base
{
_List_node_base* _M_next; ///< Self-explanatory
_List_node_base* _M_prev; ///< Self-explanatory
static void
swap(_List_node_base& __x, _List_node_base& __y);
void
transfer(_List_node_base * const __first,
_List_node_base * const __last);
void
reverse();
void
hook(_List_node_base * const __position);
void
unhook();
};
Do you have any idea where can I look for these function definitions?
This functions are in the libstdc++ sources, not the headers. In 3.4 it's in libstdc++-v3/src/list.cc
http://gcc.gnu.org/viewcvs/branches/gcc-3_4-branch/libstdc%2B%2B-v3/src/list.cc?view=markup
Have you tried compiling with -D_GLIBCXX_DEBUG ? That will enable the Debug Mode and tell you if you're using invalid iterators or anything else that causes the problem.
I just tried this simple test with GCC 3.4, with and without debug mode, and it worked fine:
#include <list>
#include <iostream>
#include <string>
int main()
{
std::list<std::string> l;
l.push_back("1");
l.push_back("2");
l.push_back("3");
l.push_back("4");
l.push_back("5");
l.push_back("6");
l.splice(l.end(), l, ++l.begin());
for (std::list<std::string>::iterator i = l.begin(), e = l.end(); i != e; ++i)
std::cout << *i << ' ';
std::cout << std::endl;
}
Modifying it further and debugging it I see that no element is destroyed and reallocated when doing the splice, so I suspect the bug is in your program. It's hard to know, as you haven't actually said what the problem is.