The Problem
When I try to insert a document into MongoDB with the C++ driver, I get the following exception message:
Wed Feb 27 15:21:38 Assertion failure p src/mongo/client/dbclientinterface.h 1096
0 assertion src/mongo/client/dbclientinterface.h:1096
From what I can tell, it seems to have something to do with the port number? dbclientinterface.h:1096 contains the following line:
MessagingPort& port() { verify(p); return *p; }
Setting up the connection (main.cpp)
mongo::DBClientConnection DBConn( "localhost" );
mongo::DBClientConnection DBConn( "localhost:27017" ); // I've also tried this...
Inserting a document (different_file.h)
while( m_Entries.size() ){
JsonBox::Value Data( m_Entries.front() );
try {
std::stringstream JSONDoc;
mongo::BSONObj BSONDoc;
Data["doc"].writeToStream( JSONDoc, false );
BSONDoc = mongo::fromjson( JSONDoc.str() );
// std::cout << Data["ns"].getString() << std::endl;
// std::cout << BSONDoc.toString() << std::endl;
// This is where the exception is thrown...
m_DBConn.insert( Data["ns"].getString(), BSONDoc );
} catch( const mongo::DBException& e ){
std::cout << e.toString() << std::endl;
}
m_EntriesMutex.lock();
m_Entries.pop();
m_EntriesMutex.unlock();
}
I dug around in the documentation briefly and stumbled across the startling fact that you can't connect to a mongodb database from the constructor. I had to change this:
mongo::DBClientConnection DBConn( "localhost" );
to this:
mongo::DBClientConnection DBConn;
DBConn.connect( "localhost" );
Related
I'm in the process of messing around with GRPC. Currently I'm using a C# web application as my GRPC server and I'm using a C++ console application as the client.
I was able to successfully connect and communicate with the server with no issue. The problem arises when
I exit the C++ console client application. Upon exiting an Access Violation is thrown.
Stack trace
MeterReaderClientCpp.exe!`anonymous namespace'::ThreadInternalsWindows::thread_body
MeterReaderClientCpp.exe!__acrt_lock
ntdll.dll!RtlpWaitOnCriticalSection()
ntdll.dll!RtlpEnterCriticalSectionContended()
ntdll.dll!RtlEnterCriticalSection()
MeterReaderClientCpp.exe!__acrt_lock(__acrt_lock_id _Lock) Line 55
MeterReaderClientCpp.exe!_free_dbg(void * block, int block_use) Line 1019
MeterReaderClientCpp.exe!free(void * block) Line 32
MeterReaderClientCpp.exe!gpr_free(void * p) Line 53
MeterReaderClientCpp.exe!`anonymous namespace'::ThreadInternalsWindows::destroy_thread() Line 142
MeterReaderClientCpp.exe!`anonymous namespace'::ThreadInternalsWindows::Join() Line 112
MeterReaderClientCpp.exe!grpc_core::Thread::Join() Line 147
MeterReaderClientCpp.exe!gc_completed_threads() Line 74
MeterReaderClientCpp.exe!stop_threads() Line 331
MeterReaderClientCpp.exe!grpc_timer_manager_set_threading(bool threaded) Line 351
MeterReaderClientCpp.exe!grpc_shutdown_internal_locked() Line 175
MeterReaderClientCpp.exe!grpc_shutdown_internal(void * __formal) Line 208
MeterReaderClientCpp.exe!`anonymous namespace'::ThreadInternalsWindows::thread_body(void * v) Line 128
GRPC Client
int main( )
{
using namespace MeterReaderWeb::Services;
using namespace google::protobuf::util;
using namespace google::protobuf;
std::cout << "Press enter\n";
std::cin.ignore( );
std::cout << "Calling Grpc service\n";
std::fstream file{ R"(C:\Certificates\certificate.cer)", std::ios::in | std::ios::beg };
if ( !file.is_open( ) )
{
std::cerr << "Failed to open file\n";
return 1;
}
std::stringstream buffer;
buffer << file.rdbuf( );
grpc::SslCredentialsOptions options;
options.pem_root_certs = buffer.str( );
auto credentials{ grpc::SslCredentials( options ) };
auto channel{ grpc::CreateChannel( "localhost:5001", credentials ) };
auto stub{ MeterReadingService::NewStub( channel ) };
ReadingPacket packet;
packet.set_status( ReadingStatus::METER_READER_SUCCESS );
packet.set_notes( "Here are some random notes" );
auto message{ packet.add_readings( ) };
message->set_customer_id( 1 );
message->set_reading_value( 10001 );
auto timestamp{ message->mutable_reading_time( ) };
timestamp->CopyFrom( TimeUtil::GetCurrentTime( ) );
grpc::ClientContext context;
StatusMessage response;
if ( auto status{ stub->AddReading( &context, packet, &response ) }; status.ok( ) )
{
std::cout << "Added reading successfully\n";
auto responseStatus{ response.status( ) };
if ( responseStatus == ReadingStatus::METER_READER_SUCCESS )
{
std::cout << "Server status: success\n"
<< "Message: " << response.message( ) << '\n';
}
}
else
{
std::cerr << "Error: " << status.error_message( ) << '\n';
std::cerr << "Error Details: " << status.error_details( ) << '\n';
}
std::cin.ignore( );
}
I heavily used the GRPC route_guide_client.cc as a guide to help me write the above application.
I've tried adding calls to both grpc_init( ) and grpc_shutdown( ) even though their client examples don't contain either calls. But adding those had no effect.
What (if anything) am I missing here? Did I forget to call/populate something that the framework is attempting to clean up upon application exit?
OK I believe I've found what was causing the issue.
In my original post I said:
I've tried adding calls to both grpc_init( ) and grpc_shutdown( ) even though
the client examples don't contain either calls. But
adding those had no effect."
This was true, but after re-reading the documentation for grpc_shutdown( ) i noticed this (emphasis mine):
The last call to grpc_shutdown will initiate cleaning up of grpc
library internals, which can happen in another thread. Once the
clean-up is done, no memory is used by grpc, nor are any instructions
executing within the grpc library. Prior to calling, all application
owned grpc objects must have been destroyed.
This is where I think I went wrong. I was calling grpc_shutdown() while I still had grpc objects in scope. To correct I scoped the grpc objects and then called grpc_shutdown() once that scope was exited. This seems to have corrected the issue.
New Grpc Client
int main( )
{
std::cout << "Press enter\n";
std::cin.ignore( );
std::cout << "Calling Grpc service\n";
grpc_init( );
{ // <- Intentionally added scope here.
grpc::SslCredentialsOptions options;
if ( auto certificate{ ReadCertificate( ) } )
options.pem_root_certs = std::move( certificate ).value( );
else return 1;
auto credentials{ grpc::SslCredentials( options ) };
auto channel{ grpc::CreateChannel( "localhost:5001", credentials ) };
auto stub{ MeterReadingService::NewStub( channel ) };
std::cout << "Sending single packet\n";
SendPacket( stub.get( ), 8000 );
std::cout << "Sending multiple packets\n";
StreamDiagnostics( stub.get( ), 3 );
}
std::cout << "Shutting down library\n";
grpc_shutdown_blocking( );
std::cout << "Shut down complete press enter to exit\n";
std::cin.ignore( );
}
I have a code with c++, which use SQLAPI++ library. In my code I've tried to open connection for mysql, then create two commands, which works with same connection, and call that command from two threads.
During execution of my code I've received exception "Connection lost during query" and "MySQL server has gone away".
Sometime I receive exception "Command out of sync, you can't run this command now".
I've tried to increase wait_timeout տօ 150 and max_allowed_package տօ 64M, but my problem is not solved.
Bellow you can find c++ code.
int main()
{
try
{
SAConnection saConnection;
saConnection.Connect("scada", "root", "123qwerty!##", SA_MySQL_Client);
saConnection.setAutoCommit(SA_AutoCommitOff);
SACommand saCommand1{&saConnection, "select * from Node"};
SACommand saCommand2{&saConnection, "select * from Node limit 1"};
// VM: TODO: saCommand1.setOption("UseStatement") = "TRUE";
// VM: TODO: saCommand2.setOption("UseStatement") = "TRUE";
saCommand1.setOption("HandleResult") = "store";
saCommand2.setOption("HandleResult") = "store";
auto f1 = std::async(std::launch::async, [&]{ saCommand1.Execute(); saConnection.Commit(); });
auto f2 = std::async(std::launch::async, [&]{ saCommand2.Execute(); saConnection.Commit(); });
f1.get();
f2.get();
//saConnection.Commit(); // BOOM!
/*
while (saCommand1.FetchNext())
std::cerr << "======== fetching a record from saCommand1" << std::endl;
while (saCommand2.FetchNext())
std::cerr << "======== fetching a record from saCommand2" << std::endl;
*/
}
catch(const SAException& ex)
{
std::cerr << "==== ex.what() is " << static_cast<const char*>(ex.ErrText()) << std::endl;
}
return 0;
}
You are using one connection from two std::async objects, probably from two threads, which is not supported. Create two connections to the database, one for each std::async.
My goal is to write a little program in c++ with boost asio that notifies me whenever an ICMP packet is received on any network interface.
The program doesn't print any errors and there are no exceptions.
But it also doesn't receive any ICMP packets sent by any program but one (the ping example of boost asio, which can be found here).
What's even stranger is the fact that the ICMP echo request packet from the boost example (after adjusting the payload and the ICMP identifier accordingly) and the default windows ICMP echo request (when using "ping" in the windows commmand line) look almost exactly the same in wireshark. The only difference beeing the identification field in the IPv4 header and thus also the ICMP checksum.
The same behaviour can be observed no matter where the echo request comes from, be it a virtual machine or another real computer in the network.
I can ping all those machines without any issues.
Disabling the windows firewall yields the same result.
OS: Windows 10 64 bit Enterprise N (10.0.10586 Build 10586)
Boost version: 1.62.0.
IDE: Microsoft Visual Studio Community 15.
Here is what I came up with:
#include <boost/asio/io_service.hpp>
#include <boost/asio/ip/icmp.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/asio/placeholders.hpp>
#include <boost/system/error_code.hpp>
#include <boost/array.hpp>
#include <boost/bind.hpp>
#include <iostream>
class ICMPReceiver {
public:
ICMPReceiver( boost::asio::io_service & IOS ):
m_sock( IOS ),
m_localEP( boost::asio::ip::icmp::v4(), 0 )
{
}
bool open() {
boost::system::error_code ec;
if ( !m_sock.is_open() ) {
m_sock.open( boost::asio::ip::icmp::v4(), ec );
if ( ec ) {
std::cerr << "Error in socket.open():\n" << ec.message() << '\n';
return false;
}
}
return true;
}
bool bind() {
boost::system::error_code ec;
m_sock.bind( m_localEP, ec );
if ( ec ) {
std::cerr << "Error in socket.bind():\n" << ec.message() << '\n';
return false;
}
}
bool startReceiving() {
try {
m_sock.async_receive_from( boost::asio::buffer( m_receiveBuffer ),
m_remoteEP,
boost::bind( &ICMPReceiver::receiveHandle,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred ) );
} catch ( std::exception const & e ) {
std::cerr << "Exception in socket.async_receive_from():\n" << e.what() << '\n';
return false;
}
return true;
}
private:
void receiveHandle( boost::system::error_code const & ec, size_t bytes ) {
if ( ec ) {
if ( ec != boost::asio::error::operation_aborted ) {
std::cerr << "Error in receiveHandle():\n" << "Code: " << ec << ": " << ec.message() << '\n';
return;
} else {
std::cerr << "operation aborted\n";
return;
}
} else {
std::cout << "ICMP packet received\n";
}
startReceiving();
}
boost::asio::ip::icmp::socket m_sock;
boost::asio::ip::icmp::endpoint m_localEP;
boost::asio::ip::icmp::endpoint m_remoteEP;
boost::array< char, 2048 > m_receiveBuffer;
};
int main() {
try {
boost::asio::io_service IOS;
ICMPReceiver receiver( IOS );
receiver.open();
receiver.bind();
receiver.startReceiving();
IOS.run();
return 0;
} catch ( std::exception const & e ) {
std::cerr << "Unhandled exception: " << e.what() << '\n';
return 1;
}
}
I'm new to libssh and trying to connect to a remote machine to run some commands. All of the connections and commands return without error, but then the program segfaults when leaving scope. What am I doing wrong?
Code
#include <string>
#include <iostream>
using namespace std;
#define SSH_NO_CPP_EXCEPTIONS
#include <libssh/libsshpp.hpp>
int main()
{
ssh::Session session;
//Set options
session.setOption(SSH_OPTIONS_HOST, "192.168.200.101");
session.setOption( SSH_OPTIONS_USER, "user" );
//Connect to host
session.connect();
//Authenticate user
session.userauthPassword( "password" );
//Open channel
ssh::Channel channel( session );
channel.openSession();
//Do something
channel.requestExec( "ps_aux" );
//Close channel
channel.sendEof();
channel.close();
//Disconnect
session.disconnect();
return 0;
}
GDB Trace
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff3a70a2f in ssh_channel_free () from /usr/local/lib/libssh.so.4
(gdb) where
#0 0x00007ffff3a70a2f in ssh_channel_free () from /usr/local/lib/libssh.so.4
#1 0x000000000059f436 in ssh::Channel::~Channel() ()
#2 0x000000000059e603 in main ()
After beating on it awhile, we have a working solution. The first hurdle was recognizing that the remote host must be a "known host". After that, for me, it was necessary to then source the environment before running my executable.
Last, I needed to give it some time to crunch with sleep( 1 ). Enjoy.
#include <iostream>
using namespace std;
#include <libssh/libsshpp.hpp>
int main()
{
int port = 22;
//Can use SSH_LOG_PROTOCOL here for verbose output
int verbosity = SSH_LOG_NOLOG;
ssh::Session session;
try
{
session.setOption( SSH_OPTIONS_LOG_VERBOSITY, &verbosity );
session.setOption( SSH_OPTIONS_PORT, &port );
session.setOption( SSH_OPTIONS_USER, "user" );
session.setOption( SSH_OPTIONS_HOST, "192.168.52.101" );
session.connect();
if( session.isServerKnown() != SSH_SERVER_KNOWN_OK )
{
if( session.writeKnownhost() != SSH_OK )
{
cout << "writeKnownHost failed" << endl;
}
else
{
session.connect();
}
}
if( session.userauthPassword( "password" ) != SSH_AUTH_SUCCESS )
{
cout << "failed auth" << endl;
}
ssh::Channel channel( session );
channel.openSession();
//Source environment if necessary, run executable
channel.requestExec( "source /path/to/set_env.sh; /path/to/executable/..." );
channel.close();
channel.sendEof();
//Unfortunate brute force step, the exec call needed some time
sleep( 1 );
}
catch( ssh::SshException e )
{
std::cout << "Error during connection : ";
std::cout << e.getError() << std::endl;
}
return 0;
}
I have this piece of code here:
These are functions used to create and stop a pthread:
void WatchdogController::conscious_process_handler_start() {
if ( debug ) cout << "WatchdogController: starting conscious process thread" << endl;
cn_pr_thread_active = true;
if ( pthread_create( &cn_pr_thread, NULL, conscious_process_handler, this ) < 0 ) {
cn_pr_thread_active = false;
throw WatchdogException( "Unable to start new thread" );
}
}
void WatchdogController::conscious_process_handler_stop() {
if ( debug ) cout << "WatchdogController: stopping conscious process thread" << endl;
cn_pr_thread_active = false;
int *retval;
pthread_join( cn_pr_thread, ( void ** )&retval );
if ( *retval < 0 ) {
delete retval;
string err = string( "Error returned by conscious_process_handler(): " ) + string( pthread_err );
throw WatchdogException( err.c_str() );
}
delete retval;
}
I use select() in function passed to pthread, and when stopped it returns an error resulting in return value from pthread being negative, but that's not the issue, I'll fix it later - problem is, that when the exception is thrown here:
throw WatchdogException( err.c_str() );
and caught here:
try {
watchdog_controller->hardware_watchdog_stop();
watchdog_controller->unconscious_process_handler_stop();
watchdog_controller->conscious_process_handler_stop();
}
catch ( HardwareWatchdogException &e ) {
cerr << "Error stopping hardware watchdog!" << endl;
cerr << e.get_reason() << endl;
string err = string( "Exception thrown by hardware watchdog controller" ) + string( e.get_reason() );
if ( log ) write_log( err.c_str() );
delete watchdog_controller;
return -1;
}
catch ( WatchdogException &e ) {
cerr << "Exception cought when exiting!" << endl;
cerr << e.get_reason() << endl;
string err = string( "Exception cought when exiting" ) + string( e.get_reason() );
if ( log ) write_log( err.c_str() );
delete watchdog_controller;
return -1;
}
I get segmentation fault then trying to access the object at this point:
cerr << e.get_reason() << endl;
What could be the reason?
Reference &e points to something, but it seems as if the address was invalid.
Here's the exception class:
class WatchdogException {
public:
/**
#brief Default constructor
*/
WatchdogException() : reason() {
}
/**
#brief Overloaded constructor - setting the error message
#param why Error message
*/
WatchdogException( const char *why ) : reason( why ) {
}
/**
#brief The destructor
*/
virtual ~WatchdogException() {
}
/**
#brief A getter for the error message
#return Returns a string containing error description
*/
virtual std::string get_reason() const {
return reason;
}
protected:
/**
#var reason String containing the error message
*/
std::string reason;
};
I am guessing that you are not properly allocating memory for retval, or that somehow you are returning an invalid pointer from cn_pr_thread, and that is why you get a segmentation fault when you call pthread_join.
In WatchDogException's constructor, are you remembering the pointer to the c-string passed in or are you making a copy of it.
If you're simply storing the pointer then when "err" goes out of scope when the exception is thrown the pointer returned by c_str() will be bad, hence your seg fault when you try and use it.