Discussion:
[exception] What's wrong with boost::get_error_info?
Markus Schweiß
2009-05-29 13:02:12 UTC
Permalink
Dear boost community,

I'm really new to using the boost library. Whatever, the first part I want to use is boost::exception. But already there start my problems:

I'm using 'boost::get_error_info<boost::throw_file>( myBoostException )' to retrieve the file name where my exception was thrown. The problem is that the returned 'const char*' pointer contains several wild characters at its end. It seems that the null-termination get lost somehow, somewhere.

The same is with 'boost::throw_function' and the string returned by 'boost::diagnostic_information( myBoostException )'!

For example, that is what I get from boost::diagnostic_information:
".\myFile.cppÍýýýý««««««««îþ(134): Throw in function MyClass::DoSomething()ÍÍÍÍÍÍ^ñ6
Dynamic exception type: class MyBoostException"

That's really strange because the strings are correctly stored to the boost::exception class attributes 'throw_function_' and 'throw_file_'.

So what do I wrong???
I would be so thankful when anyone could help me!


Following some detailed information:
- plattfrom: Windows XP SP3
- compiler: MS VC++ 8
- character set: multi-byte
- boost version: Release 1.37.0

code snippet for throwing my exception:

throw MyBoostException() << boost::throw_file( __FILE__ )
<< boost::throw_line( __LINE__ )
<< boost::throw_function( "MyClass::DoSomething()" );

code snippet for catching my exception:

catch( MyBoostException& myBoostException ) {
std::string info = boost::diagnostic_information( myBoostException );
const char* string = info.c_str();
}


My best regards,
Markus
Emil Dotchevski
2009-05-30 03:56:07 UTC
Permalink
Post by Markus Schweiß
Dear boost community,
I'm using 'boost::get_error_info<boost::throw_file>( myBoostException )' to retrieve the file name where my exception was thrown. The problem is that the returned 'const char*' pointer contains several wild characters at its end. It seems that the null-termination get lost somehow, somewhere.
The same is with 'boost::throw_function' and the string returned by 'boost::diagnostic_information( myBoostException )'!
".\myFile.cppÍýýýý««««««««îþ(134): Throw in function MyClass::DoSomething()ÍÍÍÍÍÍ^ñ6
Dynamic exception type: class MyBoostException"
That's really strange because the strings are correctly stored to the boost::exception class attributes 'throw_function_' and 'throw_file_'.
So what do I wrong???
I would be so thankful when anyone could help me!
- plattfrom:      Windows XP SP3
- compiler:       MS VC++ 8
- character set:  multi-byte
- boost version:  Release 1.37.0
throw MyBoostException() << boost::throw_file( __FILE__ )
                        << boost::throw_line( __LINE__ )
                        << boost::throw_function( "MyClass::DoSomething()" );
catch( MyBoostException& myBoostException ) {
 std::string info = boost::diagnostic_information( myBoostException );
 const char* string = info.c_str();
}
Long shot, but it looks like you have ABI conflict of some sort. Could
you post a simple, complete program that demonstrates your problems?

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode
Markus Schweiß
2009-06-02 08:11:26 UTC
Permalink
Post by Emil Dotchevski
Long shot, but it looks like you have ABI conflict of some sort. Could
you post a simple, complete program that demonstrates your problems?
Here is the complete sourcecode of a Win32 console application that reproduces my problem.
And shame on me, I forgot to mention that my application as well as the Boost libraries uses STLport version 5.0.2


#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <stdio.h>
#include <tchar.h>
#include <boost/exception.hpp>


class MyBoostException : public boost::exception
{
public:
MyBoostException() { /*do nothing*/ };
virtual ~MyBoostException() { /*do nothing*/ };
};

void DoSomething()
{
throw MyBoostException() << boost::throw_file( _T(__FILE__) )
<< boost::throw_line( __LINE__ )
<< boost::throw_function( _T("DoSomething()") );
}

int _tmain( int argc, _TCHAR* argv[] )
{
try {
DoSomething();
} catch( MyBoostException& ex ) {

boost::shared_ptr<const int> pLine =
boost::get_error_info<boost::throw_line>(ex);

boost::shared_ptr<const char* const> pMethod =
boost::get_error_info<boost::throw_function>(ex);
const char* sMethod = *pMethod;

boost::shared_ptr<const char* const> pFile =
boost::get_error_info<boost::throw_file>(ex);
const char* sFile= *pFile;

std::string info = boost::diagnostic_information( ex );
const char* sString = info.c_str();

}
return 0;
}
Emil Dotchevski
2009-06-02 19:04:21 UTC
Permalink
Post by Markus Schweiß
Post by Emil Dotchevski
Long shot, but it looks like you have ABI conflict of some sort. Could
you post a simple, complete program that demonstrates your problems?
Here is the complete sourcecode of a Win32 console application that reproduces my problem.
And shame on me, I forgot to mention that my application as well as the Boost libraries uses STLport version 5.0.2
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <stdio.h>
#include <tchar.h>
#include <boost/exception.hpp>
class MyBoostException : public boost::exception
{
MyBoostException() { /*do nothing*/ };
virtual ~MyBoostException() { /*do nothing*/ };
};
void DoSomething()
{
throw MyBoostException() << boost::throw_file( _T(__FILE__) )
<< boost::throw_line( __LINE__ )
<< boost::throw_function( _T("DoSomething()") );
}
int _tmain( int argc, _TCHAR* argv[] )
{
try {
DoSomething();
} catch( MyBoostException& ex ) {
boost::shared_ptr<const int> pLine =
boost::get_error_info<boost::throw_line>(ex);
boost::shared_ptr<const char* const> pMethod =
boost::get_error_info<boost::throw_function>(ex);
const char* sMethod = *pMethod;
boost::shared_ptr<const char* const> pFile =
boost::get_error_info<boost::throw_file>(ex);
const char* sFile= *pFile;
std::string info = boost::diagnostic_information( ex );
const char* sString = info.c_str();
}
return 0;
}
I am puzzled, but here is another guess.

Boost::throw_line, boost::throw_function and boost::throw_file have
special handling in Boost Exception; adding them to exceptions does
not use anything from STL. So here is something to try: print *pLine,
sMethod and sFile directly. If you get correct strings, then the
problem could be in some interference between STLport and
std::ostringstream. Step into boost::diagnostic_information and see
what is passed into std::ostringstream's operator<<. If the data
entering it is good but the output from .str() is bad, it's definitely
an issue with STLport's installation.

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode
Markus Schweiß
2009-06-03 08:47:21 UTC
Permalink
Post by Emil Dotchevski
I am puzzled, but here is another guess.
Boost::throw_line, boost::throw_function and boost::throw_file have
special handling in Boost Exception; adding them to exceptions does
not use anything from STL. So here is something to try: print *pLine,
sMethod and sFile directly. If you get correct strings, then the
problem could be in some interference between STLport and
std::ostringstream. Step into boost::diagnostic_information and see
what is passed into std::ostringstream's operator<<. If the data
entering it is good but the output from .str() is bad, it's definitely
an issue with STLport's installation.
It seems that std::ostringstream has nothing to do with my problems. But the STLport installation might still be the guilty party.

I detected the source of annoyance within file 'get_error_info.hpp', at line 49 respectively 67, where a string wrapper instance is created:

shared_ptr<strwrap> s(new strwrap(x.throw_function_));
respectively
shared_ptr<strwrap> s(new strwrap(x.throw_file_));

Initialization of attribute 'str' (a std::string) within strwrap's c'tor, is the point where the null-termination get lost.

For now I try to compile my application with a newer STLport version, respectively without any STLport, to see what happen. Progress will be reported soon...
Emil Dotchevski
2009-06-03 16:47:06 UTC
Permalink
Post by Markus Schweiß
For now I try to compile my application with a newer STLport version, respectively without any STLport, to see what happen. Progress will be reported soon...
I also recommend upgrading to the newest version of Boost;
get_error_info now returns a raw pointer, not shared_ptr. It will
probably save you time to make the switch to this new behavior sooner
rather than later.

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode

Loading...