std::system_error occurs at Protobuf ParseFromZeroCopyStream() - c++

I'm testing protobuf with zlib compression.
I wrote some c++ sample code using protobuf 3.8.0, but the following error occurred at calling ParseFromZeroCopyStream() at Ubuntu.
terminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1
(core dumped)
what can I do?
I tried to replace ParseFromZeroCopyStream() with ParseFromBoundedZeroCopyStream().
That results in no core dump, but ParseFromBoundedZeroCopyStream() returned false.
test.proto
syntax = "proto2";
package test;
message Msg
{
required uint32 data = 1;
}
test.cc
#include <iostream>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/io/gzip_stream.h>
#include "test.pb.h"
using namespace std;
using namespace google::protobuf;
using namespace test;
int main(void)
{
Msg srcMsg;
srcMsg.set_data(1);
long sSize = srcMsg.ByteSizeLong();
cout << "SerializedSize = " << sSize << endl;
char * compressedMsg = new char[sSize];
io::ArrayOutputStream aos(compressedMsg, sSize);
io::GzipOutputStream gos(&aos);
long cSize;
if (srcMsg.SerializeToZeroCopyStream(&gos) == true)
{
gos.Close();
cSize = aos.ByteCount();
cout << "compression success : " << cSize << " bytes" << endl;
}
else
{
cout << "compression error" << endl;
return 1;
}
Msg targetMsg;
io::ArrayInputStream ais(compressedMsg, cSize);
io::GzipInputStream gis(&ais);
if (targetMsg.ParseFromZeroCopyStream(&gis) == false)
{
cout << "decompression error" << endl;
}
else
{
cout << "decompression success : " << targetMsg.ByteSizeLong() << " bytes" << endl;
cout << "data = " << targetMsg.data() << endl;
}
delete[] compressedMsg;
return 0;
}
I expect that decompression succeeds.

You will need to learn to use a debugger to investigate further why exactly this "unknown error: -1" is thrown - if possible.
That being said, unknown library errors is sometimes caused by a failed memory allocation or in rarer cases some other ressource constraint like failing to start a thread/process, etc.

Related

Segmentation fault while declaring an iterator in c++ example of leveldb

I was trying to apply an iteration to my leveldb file, but unfortunately I couldn't get the result. The problem that I'm facing is a segmentation fault in using the pointer of the iterator. I used gdb And I got that the problem is in the line
leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
(I added before some values to this file /tem/userDb , and the add is working good .)
#include <assert.h>
#include <leveldb/db.h>
#include <iostream>
#include <sstream>
using namespace std;
void iteration(leveldb::DB* db)
{
leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
for (it->SeekToFirst(); it->Valid(); it->Next())
{
cout << "key :" << it->key().ToString() << " : "
<< "value:" << it - > value().ToString() << endl;
}
if (false == it->status().ok())
{
cerr << "An error was found during the scan" << endl;
cerr << it->status().ToString() << endl;
}
delete it;
}
int main(int argc, char *argv[])
{
leveldb::DB* db;
leveldb::Options options;
options.create_if_missing = true;
// erase error if the database exists
options.error_if_exists = true;
leveldb::Status s = leveldb::DB::Open(options, "/tmp/userDb", &db);
if (!s.ok())
cerr << s.ToString() << endl;
iteration(db);
delete db;
}
Not familiar with the leveldb API, but you're using db regardless of whether s.ok() is true or false. I'd assume that if s.ok() is false, db is either NULL, or in a state such that iteration or other operations won't work.
You should change the code to:
if (!s.ok()) {
cerr << s.ToString() << endl;
return -1;
}

Memory access violation error c++

I'm trying to exchange messages using multiple covert channels.
So, basically, first i need to select the channel that i want to use for communication and then select the "destination_ip" of the user that i want to chat with and after that the
processMessage()
is called. Now, to move from one channel to another I have to close the existing connection and then open a new connection with the new channel that i want to use. My code below is modified to keep using the same channel after closing the connection and contain only the things that you need.
#include <channelmanager.hpp>
#include <thread>
#include <iostream>
#include <boost/test/unit_test.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <stdio.h>
#include <string.h>
#include <fstream>
#include <openssl/hmac.h>
struct CommunicationFixture {
CommunicationFixture() {
channelmanager.setErrorStream(&cout);
channelmanager.setOutputStream(&cout);
destination_ip = "";
channel_id = channelmanager.getChannelIDs()[0];
}
library::ChannelManager channelmanager;
vector<string> last_adapters;
string destination_ip;
string channel_id = "";
int processMessage(string message) {
if (message.compare("exit") == 0) {
channelmanager.closeConnection(destination_ip);
return 1;
}
vector<string> arguments;
boost::split(arguments, message, boost::is_any_of(" "), boost::token_compress_on);
if (arguments[0].compare("argument") == 0) {
if (arguments.size() < 2) {
cout << "Not enough arguments" << endl;
return 0;
}
string argument_list = arguments[1];
for (unsigned int i = 2; i < arguments.size(); i++) {
argument_list += " " + arguments[i];
}
channelmanager.setChannelArguments(destination_ip, argument_list);
cout << "Set channel argument to '" << argument_list << "'." << endl;
return 0;
}
if (message.compare("help") == 0) {
cout << "Help not available in chat mode. Close chat first with 'exit'" << endl;
return 0;
}
channelmanager.openConnection(destination_ip, channel_id);
channelmanager.sendMessage(destination_ip, message);
return 0;
}
int close(string destination){
cout << "closing.." << endl;
channelmanager.closeConnection(destination); //I believe i have the error because of this!
return 0;
}
};
BOOST_FIXTURE_TEST_SUITE(communication, CommunicationFixture)
BOOST_AUTO_TEST_CASE(basic_communication) {
selectAdapterId(0);
cout << "Test" << endl << endl;
printCommands();
cout << "Enter your command:" << endl;
string command;
int code = 0;
while (code != 2) {
std::getline(cin, command);
code = processCommand(command);
if (code == 1) {
// chat
cout << "chat started.." << endl;
int chatCode = 0;
while (chatCode != 1) {
std::getline(cin, message);
close(destination_ip);
chatCode = processMessage(message);
channelmanager.setErrorStream(&cout);
}
cout << "chat ended." << endl;
}
}
}
BOOST_AUTO_TEST_SUITE_END()
Note that, i think that the error happens due to the
function close()
because without it i don't get any errors. and the error doesn't happen immediately but after exchanging some messages. Here's the error:
unknown location(0): fatal error: in
"communication/basic_communication": memory access violation at
address: 0x00000024: no mapping at fault address
communicationTest.cpp(325): last checkpoint: "basic_communication"
test entry
Memory access violation happen when you are trying to access to an unitialized variable, in this case the channelmanager.
I can only see that you initialize channelmanager in the processMessage() method and you are closing the connection before initializing the channelmanager as it happen in:
close(destination_ip);
chatCode = processMessage(message);
Either you change the initialization or do not close it before the processMessage() method.
Memory access violation is also called a segmentation fault (or segfault), occurs when the program tries to access a memory location that doesn't exist, or is otherwise inaccessible. We call this trying to access an illegal memory location. That memory is either non-existent or we aren't aren't allowed to touch it.
If the first input from user is 'exit', which is going to call
if (message.compare("exit") == 0) {
channelmanager.closeConnection(destination_ip);
return 1;
}
In this case, destination_ip isn't initialised.

Why does boost's managed_mapped_file :: shrink_to_fit behave differently on Windows and Linux?

This is about C ++ library boost.
The managed_mapped_file :: shrink_to_fit function works differently on Linux and Windows.
On Linux, this function succeeds even if the target instance exists.
However, on Windows, this function will fail if the target instance exists.
Is this correct behavior?
It seems correct to do the same behavior, is this a bug?
I put the sample code below.
Compilation environment
boost:version.1.65.1
Windows
VisualStudio2017
WSL(Ubuntu16.04)
Linux
UbuntuServer17.10,
Clang++5.0,
g++7.2.0
Compile with
clang++-5.0 -std=c++1z ./test.cpp -o test -lpthread
#define BOOST_DATE_TIME_NO_LIB
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <vector>
#include <iostream>
namespace bip = boost::interprocess;
using intAlloc = bip::allocator<int, bip::managed_mapped_file::segment_manager>;
using intVec = std::vector<int, intAlloc>;
int main() {
bip::managed_mapped_file *p_file_vec;
intVec *vecObj;
std::string fileName = "tmp.dat";
size_t fileSize = 1024 * 1024 * 1;
bip::file_mapping::remove(fileName.c_str());
p_file_vec = new bip::managed_mapped_file(bip::create_only, fileName.c_str(), fileSize);
vecObj = p_file_vec->construct<intVec>("myVecName")(p_file_vec->get_allocator<int>());
for (size_t i = 0; i < 10; i++)
{
vecObj->push_back(1 + 100);
}
p_file_vec->flush();
try
{ //Fail when execute on Windows(WSL),but Success on Linux(Ubuntu17.10).
std::cout << "try to shrink:pointer has existed yet!" << std::endl;
bip::managed_mapped_file::shrink_to_fit(fileName.c_str());
std::cout << "success to shrink!" << std::endl;
}
catch (const boost::interprocess::interprocess_exception &ex)
{
std::cerr << "fail to shrink!" << std::endl;
std::cerr << ex.what() << std::endl;;
}
std::cout <<"please pless enter key."<< std::endl;
std::cin.get();
try
{ //Success when execute on Windows(WSL) and Linux(Ubuntu17.10).
delete p_file_vec;
std::cout << "try to shrink:pointer has deleted!" << std::endl;
bip::managed_mapped_file::shrink_to_fit(fileName.c_str());
std::cout << "success to shrink!" << std::endl;
}
catch (const std::exception& ex)
{
std::cerr << "fail to shrink!" << std::endl;
std::cerr << ex.what() << std::endl;;
}
std::cout << "please pless enter key." << std::endl;
std::cin.get();
}
Don't use new and delete in C++ (rule of thumb).
Apart from that
delete p_file_vec;
does NOT delete anything physical. It effectively disconnects from the mapped file. This is also why shrink_to_fit works: the documentation explicitly says:
If the application can find a moment where no process is attached it can grow or shrink to fit the managed segment.
And here
So, in short: the behaviour is correct on both platforms. It's just UNDEFINED what happens in your case when you shrink while the mapped file is in use (on Ubuntu).
Fixed Code:
Live On Coliru
#include <boost/interprocess/managed_mapped_file.hpp>
#include <iostream>
#include <vector>
namespace bip = boost::interprocess;
using intAlloc = bip::allocator<int, bip::managed_mapped_file::segment_manager>;
using intVec = std::vector<int, intAlloc>;
int main() {
std::string const fileName = "tmp.dat";
bip::file_mapping::remove(fileName.c_str());
{
bip::managed_mapped_file file_vec(bip::create_only, fileName.c_str(), 1l << 20);
auto *vecObj = file_vec.construct<intVec>("myVecName")(file_vec.get_allocator<int>());
for (size_t i = 0; i < 10; i++) {
vecObj->push_back(1 + 100);
}
}
try { // Success when execute on Windows(WSL) and Linux(Ubuntu17.10).
std::cout << "try to shrink:pointer has deleted!" << std::endl;
bip::managed_mapped_file::shrink_to_fit(fileName.c_str());
std::cout << "success to shrink!" << std::endl;
} catch (const std::exception &ex) {
std::cerr << "fail to shrink!" << std::endl;
std::cerr << ex.what() << std::endl;
;
}
}

C++ MySQL-connector on Arch-Linux/arm

I have written a program using C++/C, the MySQL C++ connector and ncurses/CDK. It compiles just fine, and runs fine as well on an x86/64 architecture. It crashes, however, when run on a Raspberry Pi B+ (ArchLinux).
I realize this is a pretty hard question to answer, but maybe someone more experienced can help.
Here's the (hopefully) relevant Code:
//Open Connection to the Database
nrpeout::MYSQL_CON localhost("127.0.0.1", 3306, "root", "toor");
//localhost.write_attributes_to_console();
con = localhost.open_database_connection();
//Create a new object of type nrpeoutputquery
nrpeout::Nrpeoutputquery current_query("SELECT * FROM nrpeout", con);
//Execute query
res = current_query.execute_query();
//Close Database Connection
localhost.close_database_connection(con);
} catch (sql::SQLException &e) {
//Handle SQL-Exceptions
std::cout << "# ERR: SQLException in " << __FILE__;
std::cout << "(" << __FUNCTION__ << ") on line "
<< __LINE__ << std::endl;
std::cout << "# ERR: " << e.what();
std::cout << " (MySQL error code: " << e.getErrorCode();
std::cout << ", SQLState: " << e.getSQLState() << " )" << std::endl;
} catch(...) {
//Handle Standard Exceptions
std::cout << "Unknown Exception raised. Please contact your Administrator" << std::endl;
}
nrpeout::NrpeResultSet* currentResults = new nrpeout::NrpeResultSet(res);
Using Valgrind and GDB, I have tried to narrow the error down to the line where I create the object "currentResults".
Here's the member function that saves the query results:
nrpeout::NrpeResultSet::NrpeResultSet(sql::ResultSet* res)
{
for (unsigned int i = 0; i < res->rowsCount(); ++i)
{
res->next();
std::string command = res->getString("command");
//Shorten the String
size_t posCommand = command.find("_");
std::string shortened_command = command.substr(posCommand+1);
int ret = res->getInt("ret");
std::string text = res->getString("text");
//Shorten the Text
size_t posText = text.find("|");
std::string shortened_text = text.substr(0, posText-1);
std::string last_updated = res->getString("last_updated");
this->results.push_back(Row(shortened_command, ret, shortened_text, last_updated));
}
Well, you are not catching an exception, which you may want to handle. InvalidInstanceException is thrown when using closed databse connections, statements or resultsets.
My suggestion is to run your code with a gdb and catch exceptions:
gdb ./some-program
$ catch throw
$ r
This will break after each exception being thrown. (But also includes handled exceptions, so there may be quite a few breaks, depending on how long it takes you to get to the important part.)

Crash writing simple WSO2/C++ web service client

Has any been able to successfully run with a client using the WSO2/C++ web services package? I've tried just about everything I can think of yet every time I try to run a very simple client I get a crash. Here's some sample code from one of their example programs...
#include <stdio.h>
#include <WSRESTClient.h>
#include <OMElement.h>
#include <iostream>
#include <AxisFault.h>
using namespace std;
using namespace wso2wsf;
int _tmain(int argc, _TCHAR* argv[])
{
WSRESTClient * sc = new WSRESTClient("http://localhost:9090/axis2/services/echo/echoString");
try
{
sc->initializeClient("echo_rest.log", AXIS2_LOG_LEVEL_TRACE);
}
catch (AxisFault & e)
{
cout << endl << "Error: " << e << endl;
return 0;
}
Options * op = sc->getOptions();
op->setHTTPMethod(AXIS2_HTTP_GET);
sc->setOptions(op);
{
OMNamespace * ns = new OMNamespace("http://ws.apache.org/axis2/services/echo", "ns1");
OMElement * payload = new OMElement(NULL,"echoString", ns);
OMElement * child = new OMElement(payload,"text", NULL);
child->setText("Hello World!");
cout << endl << "Request: " << payload << endl;
OMElement * response;
try
{
response = sc->request(payload, "http://ws.apache.org/axis2/c/samples/echo/soap_action");
if (response)
{
cout << endl << "Response: " << response << endl;
}
}
catch (AxisFault & e)
{
cout << endl << "Error: " << e << endl;
}
delete payload;
}
delete sc;
return 0;
}
I get a crash every time at the point of the WRESTClient object construction. It appears to be an issue somewhere in the WSO2 code but I don't get any error message indicating what the exact problem is. My next step will be to build against the source for WSO2 and step through the code which is crashing but I'm hoping someone has encountered this issue before and has some immediate feedback.
Have you considered putting a try/catch-all block around the WRESTClient object construction? If you're core dumping on this line then the chances are that it's throwing an exception, and if you catch it then you might be able to get more useful error information out of that exception.
Other than that, time to break out the debugger as you suggested.