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

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

Related

Creating logical device in Vulkan returns -8, but only sometimes

While using a class to hold my window class and Vulkan class, this error VK_ERROR_FEATURE_NOT_PRESENT is returned when I use vkCreateDevice however, when I put the same code the class is running into the main class, it works completely fine. I also had a similar problem with getting the instance extensions via SDL_Vulkan_GetInstanceExtensions.
working main.cpp
window.createWindow();
engine.window = window.window;
try {
engine.initialize();
}
catch (XiError error) {
std::cout << "Error " << error.code << ": " << error.definition << std::endl;
}
window.instance = engine.getVkInstance();
VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(engine.physicalDevice, &deviceProperties);
std::cout << deviceProperties.deviceName << ", Driver Version " << deviceProperties.driverVersion << std::endl;
try {
window.createSurface();
}
catch (XiError error) {
std::cout << "Error " << error.code << ": " << error.definition << std::endl;
}
window.mainLoop();
vkDestroyDevice(engine.logicalDevice, nullptr);
vkDestroySurfaceKHR(engine.instance, window.surface, nullptr);
vkDestroyInstance(engine.instance, nullptr);
SDL_DestroyWindow(window.window);
SDL_Quit();
not working main.cpp
try {
app.run();
}
catch (XiError error) {
std::cout << "Error " << error.code << ": " << error.definition << std::endl;
}
VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(app.engine.physicalDevice, &deviceProperties);
std::cout << deviceProperties.deviceName << ", Driver Version " << deviceProperties.driverVersion << std::endl;
app.window.mainLoop();
app.shutDown();
app.run()
window.createWindow();
engine.window = window.window;
engine.createVulkanInstance();
window.instance = engine.getVkInstance();
window.createSurface();
engine.getPhysicalDevices();
engine.selectPhysicalDevice();
engine.createLogicalDevice();
window.mainLoop();
app.shutDown()
vkDestroyDevice(engine.logicalDevice, nullptr);
vkDestroySurfaceKHR(engine.instance, window.surface, nullptr);
vkDestroyInstance(engine.instance, nullptr);
SDL_DestroyWindow(window.window);
SDL_Quit();
window engine and app are pre-defined by my own classes
I've tried manually adding the different required and supported extensions, and it works, but it feels hacky and is quite a large bulk of code. If this is a weird out of scope error, I've really no idea. if any other code is needed I'll be happy to provide it and the GitHub can also be found here: https://github.com/XiniaDev/Xinia-Engine
I think your problem is that requiredFeatures in XiEngine is not initialised. You set a few values to true, but I think you need a memset(&requiredFeatures, 0, sizeof(requiredFeatures)); or similar at the start of XiEngine::XiEngine to fix it.

std::system_error occurs at Protobuf ParseFromZeroCopyStream()

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.

How to prevent open-file too much in c++ using MySQL connector

It show error code : Can't create socket(24) , after I survey I know that is reach the open_files_limit,I checked the show global variables like 'open%';
in MySQL and value is 5000000,so my code must some problem in it.
here's my simple code:
class DB {
public:
double query1();
double query2();
double query3();
};
main() {
DB handler;
for(int i=0;i<100000;i++) {
handler.query1();
handler.query2();
handler.query3();
}
}
I wrote a class handle the 3 query and run it in the loop, how can I prevent open-file limit problem in this class
here's query code :
double query1(string pair) {
double get_prob;
try {
/* Create a connection */
driver = get_driver_instance();
con = driver->connect("localhost", "root", "nlpgroup");
/* Connect to the MySQL test database */
con->setSchema("em_im");
stmt = con->createStatement();
stringstream stmvar;
stmvar << "select prob from em where pair='" << pair << "'";
string stmvarstr = stmvar.str();
cout << stmvarstr << endl;
res = stmt->executeQuery(stmvarstr); // replace with your statement
while (res->next()) {
get_prob = atof(res->getString(1).c_str());
}
res->close();
stmt->close();
con->close();
delete res;
delete stmt;
delete con;
} catch (sql::SQLException &e) {
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
cout << "# ERR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
}
return get_prob;
}
show global variables like 'open%'; in MySQL
Apart from MySQL, your OS might impose limits, too. For linux, have a look at /etc/security/limits.conf, on Windows, this answer might help you out.
However, if you need one and the same connection that often one after another time, it might be a better choice to open it once and keep it open until your program terminates. This will additionally give you better performance - and you can improve performance even more using a prepared statement instead. I added this to the example below already...
class DB
{
std::unique_ptr <sql::Connection> con;
std::unique_ptr <sql::PreparedStatement> stmt;
public:
DB();
double query1(std::string const& pair);
};
DB::DB()
: con(get_driver_instance()->connect("localhost", "root", "nlpgroup"))
{
con->setSchema("em_im");
// you might prefer a prepared statement
stmt.reset(con->prepareStatement("SELECT prob FROM em WHERE pair = ?"));
}
double DB::query1(std::string const& pair)
{
double get_prob = 0.0;
try
{
stmt->setString(1, pair);
std::unique_ptr < sql::ResultSet > res(stmt->execute());
while (res->next())
{
get_prob = atof(res->getString(1).c_str());
}
}
catch(sql::SQLException& e)
{
/* ... */
}
return get_prob;
}
Usage of std::unique_ptr assures that all objects are deleted correctly even in case of an exception - which, by the way, your code did not. I did not call close explicitely - it will be called in the objects' destructors anyway, so this is fine.
Be aware that now the constructor can throw an exception, too, so you need a try - catch in the main function, too. Depending on your needs, you then could leave out the try - catch in the query functions. This changes behaviour, however: Leaving as is results in all the queries being executed, even if one fails in between, whereas dropping it results in aborting the loop.

How to handle data type errors with UserException in MongoDB with the C++ driver

Windows 7 64 SP1
MongoDB 2.2.0
C++ driver
MSVS 2010
According to:
http://api.mongodb.org/cplusplus/2.2.0/classmongo_1_1_b_s_o_n_element.html#a692f3eecb505eae2181eb938b7680fbe
Double() (and like functions) should "throw a UserException if the element is not of the required type."
My code:
BSONObj a_document = BSON("a_string"<<"A string");
try
{
a_document["a_string"].Double();
}
catch(mongo::UserException ue)
{
cout << ue.toString() << endl;
}
But it doesn't get caught. Intead it asserts:
Sun Dec 09 16:04:28 Assertion: 13111:wrong type for field (a_string) 2 != 1
Sun Dec 09 16:04:28 dev: lastError==0 won't report:wrong type for field (a_string) 2 != 1
What am I doing wrong? I want to catch and handle the data type exceptions myself.
Thanks!
My feeling from looking through the cocumentation and headers is that the documentation is inaccurate at this point, or that some option was used that disables exceptions from MongoDB.
Try the following code:
BSONObj a_document = BSON("a_string"<<"A string");
try
{
a_document["a_string"].Double();
}
catch(mongo::UserException& ue)
{
cout << "UserException: " << ue.toString() << endl;
}
catch(mongo::MsgAssertionException& ex)
{
cout << "MsgAssertionException: " << ex.toString() << endl;
}
catch(mongo::DBException& ex)
{
cout << "DBException: " << ex.toString() << endl;
}
catch(std::exception& ex)
{
cout << "std::exception: " << ex.what() << endl;
}
to see which exception gets actually thrown (if any).

boost::iostreams::mapped_file_sink throws unknown exception

Could you guys help me decypher unknown exception that is thrown by boost::iostreams::mapped_file_sink ?
My configuration
boost 1.51
Visual Studio 2012 on Windows 7
GCC 4.7 on Ubuntu
Here is the code I have
try
{
boost::iostreams::mapped_file_params params_;
boost::iostreams::mapped_file_sink sink_;
params_.length = 0;
params_.new_file_size = 1024;
params_.path = "./test.bin";
sink_.open(params_);
sink_.close();
}
catch (std::ios::failure& ex)
{
std::cout << "\t" << "what: " << ex.what() << "\n";
}
catch (std::system_error& ex)
{
std::cout << "\t" << "code: " << ex.code() << " what: " << ex.what() << "\n";
}
catch (std::runtime_error& ex)
{
std::cout << "\t" << ex.what() << "\n";
}
catch (boost::archive::archive_exception& ex)
{
std::cout << "\t" << ex.what() << "\n";
}
catch (boost::exception& ex)
{
std::cout << "blah\n";
}
catch (std::exception& ex)
{
std::cout << "\t" << ex.what() << " --- " << typeid(ex).name() << "\n";
}
It always works in Windows.
In Ubuntu it creates empty file of given size but throws exception on open(). Subsequent execution of the code if exists doesn't cause exception.
The worst part is that I can't see the reason of the exception. I can only catch std::exception whose what() returns meaningless "std::exception".
In desperate attempt to find out what's wrong I output typeid(ex).name() which shows
N5boost16exception_detail10clone_implINS0_19error_info_injectorISt9exception
which according to Google means: boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<std::exception> >
Any ideas what's wrong?
You could run the code in a debugger and set a breakpoint in the function which actually throws an exceptions, e.g., __cxa_throw. The name of the function may be different on your system: use nm -po program | less and search for a function containing throw. Set a breakpoint in the one(s) which look most likely as if they are created by the system. If there are only few exceptions being thrown, you can also set a breakpoint into std::exception::exception().
After 50 mins of guessing I found out that problem was in length field. The documentation doesn't say that but its default value has to be -1 as stated in source code
BOOST_STATIC_CONSTANT(size_type, max_length = static_cast<size_type>(-1));
I intuitively assumed that if I set new_file_size to be more than zero it would ignore length.