boost::iostreams::mapped_file_sink throws unknown exception - c++

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.

Related

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

Get Exception Type

I was wondering if there's a way to get an string representation of an errors type/name from std::exception. Let's say I catch std::exception &err, is there a way to say something like err.getName() or err.getType(). I have a project that can throw a wide variety of errors, but I want to get the exact type if it has not been caught by something else. I'll show what I generally mean.
For simplicity sake, let's say libraryA has several uniquely defined exception types (libraryA::Exception_# where # is replaced by a number to uniquely identify the error).
Here's some simple code for this:
try{
doSomeTaskThatMightThrowAnError();
}catch(libraryA::Exception_1 &err){
std::cout << "Error type 1: " << err.what() << std::endl;
}catch(libraryA::Exception_2 &err){
std::cout << "Error type 2: " << err.what() << std::endl;
}catch(libraryA::Exception_3 &err){
std::cout << "Error type 3: " << err.what() << std::endl;
}catch(std::exception &err){
std::cout << "Unknown error: " << err.what() << std::endl;
}
Is there some way within catch(std::exception &err)'s block that I can say std::cout << "Unknown error type: " << err.getType() << '\n' << "Error message: " << err.what() << std::endl;
I want to catch std::exception as a precaution in case nothing else catches the error, but I want to be able to identify the exact error type so I may update my code and include another catch statement for it. Is this possible?
You can always use typeid(e).name() (remember to include <typeinfo> header).
But very little is guaranteed about the name so produced.
With Visual C++ it's nice and readable, with g++ it's mangled so that you practically need to use some compiler-specific functionality to demangle it.

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

How to add information about the topmost call/context to an exception

I would like to add information on what the program was about to do to my
exception handling. The old code had one big try-block around everything:
try {
read_cfg(); // a sub call might throw runtime_error
operation1();
operation2();
}
catch (std::exception& e) {
std::cerr
<< "Error: " << e.what() << ", "
// FIXME: also show what we were trying to do
// FIXME: and what a user could try
<< "\n";
}
Example error message:
Error: file "foo.cfg" not found, while reading configuration.
Please make sure the file exists.
I converted the try-block into three blocks, but this feels odd:
try {
read_cfg(); // a sub call might throw runtime_error
}
catch (std::exception& e) {
std::cerr
<< "Error: " << e.what() << ", "
<< "while reading configuration."
<< "\n";
}
try {
operation1();
}
catch (std::exception& e) {
std::cerr
<< "Error: " << e.what() << ", "
<< "while performing operation 1."
<< "\n";
}
try {
operation2();
}
catch (std::exception& e) {
std::cerr
<< "Error: " << e.what() << ", "
<< "while performing operation 2."
<< "\n";
}
I also tried to introduce one exception class per call (read_cfg_exception,
operation1_exception, operation2_exception). Since in read_cfg() the call to
open might throw, I catch its exception and convert it to a
read_cfg_exception, thereby saving the additional information, that something
whent wrong "while reading configuration". Yet this does not feel right either:
class read_cfg_exception;
void open(std::string name); // might throw std::runtime_error
void read_cfg()
{
try {
open("foo.cfg");
}
catch (std::runtime_error& e) {
throw read_cfg_exception(e.what() + "while reading configuration");
}
}
Therefor I have the question: What is a good pattern to show the additional
information of what the program was doing while the error occured.
take a look at POCO (c++ library) throwing system, that should answer all your questions, you'll learn a lot from that and many good style rules too. The answare to your question will be really long unfortunately (at least I don't know how to make it short).
Anyway don't implement something that makes your code not readable, in your example code is not readable and then not maintainable wich is not wanted.

catching exception from boost::filesystem::is_directory

I am currently catching errors from boost::filesystem::is_directory and showing the error to the user by calling "what()" on the exception. This gives the reason for failure but the error is strange to the user. For example:
boost::filesystem::is_directory: Access is denied
How can I catch the boost error and figure out what the actual cause is, so I can show a nicer error message?
By "nicer error message" would you mean something like
#include <iostream>
#include <boost/filesystem.hpp>
int main()
{
boost::filesystem::path p("/proc/1/fd/1");
try {
boost::filesystem::is_directory(p);
} catch(const boost::filesystem::filesystem_error& e)
{
if(e.code() == boost::system::errc::permission_denied)
std::cout << "Search permission is denied for one of the directories "
<< "in the path prefix of " << p << "\n";
else
std::cout << "is_directory(" << p << ") failed with "
<< e.code().message() << '\n';
}
}