HI,

If I compile QPID (using Proton) on Windows 10 in RELEASE mode, the
application trying to use the QPID client gets aborted by windows when it
tries to create a QPID connection.  The abort is called on the last line of
the following piece of code i.e. on the QPID connection creation:
    this->QPIDCredentials.IPAddress = "192.168.1.100";
    this->QPIDCredentials.Port = "5672";
    std::string QPIDBrokerDetails = this->QPIDCredentials.IPAddress + ":" +
this->QPIDCredentials.Port;
    std::string Options = "{protocol:amqp1.0, container_id: MyApp}";
    this->QPIDConnection = new
qpid::messaging::Connection(QPIDBrokerDetails, Options);            //Abort
called here

If I compile QPID (using Proton) on Windows 10 in DEBUG mode and try and
create a connection, the program executes as expected, but the following
exceptions are written to the console:
Exception at 0x7ffa0b42f218, code: 0xe06d7363: C++ exception, flags=0x1
(execution cannot be continued) (first chance) at
c:\boost_1_65_0\boost\throw_exception.hpp:69

Exception at 0x7ffa0b42f218, code: 0xe06d7363: C++ exception, flags=0x1
(execution cannot be continued) (first chance) at
c:\users\me\dev\qpid\qpid-cpp\src\qpid\types\variant.cpp:154

Multiple exceptions are written to the console, but in summary they occur
on the following lines of code:
src\qpid\types\variant.cpp:154
src\qpid\types\variant.cpp:173
src\qpid\types\variant.cpp:246

Using the debug version, the stack track to line 154 (and hence the first
exeption) is as follows:
1   qpid::types::VariantImpl::convertFromString<__int64>
Variant.cpp           154 0x7ffa02e47bad
2   qpid::types::VariantImpl::asInt64
Variant.cpp           518 0x7ffa02e3d5e9
3   qpid::types::Variant::asInt64
Variant.cpp           872 0x7ffa02e39726
4   qpid::types::Variant::parse
Variant.cpp           846 0x7ffa02e39302
5   qpid::messaging::AddressParser::readSimpleValue
AddressParser.cpp     210 0x7ff9f1ca0355
6   qpid::messaging::AddressParser::readValueIfExists
AddressParser.cpp     151 0x7ff9f1ca05c2
7   qpid::messaging::AddressParser::readValue
AddressParser.cpp     146 0x7ff9f1ca04fb
8   qpid::messaging::AddressParser::readKeyValuePair
AddressParser.cpp     128 0x7ff9f1ca06d3
9   qpid::messaging::AddressParser::readMapEntries
AddressParser.cpp     120 0x7ff9f1ca10a2
10  qpid::messaging::AddressParser::parseMap
AddressParser.cpp     70  0x7ff9f1c9fb35
11  qpid::messaging::Connection::Connection
Connection.cpp        50  0x7ff9f1ca3fd9
12  BasicConnection::BasicConnection
ExternalInterface.cxx 51  0x7ff6e6661151
13  ExternalInterface::ExternalInterface
ExternalInterface.h   140 0x7ff6e66a9648

The code for convertFromString() extracted from variant.cpp is as follows:

    template<class T>
    typename enable_if<is_signed<T>::value, T>::type convertFromString()
const
    {
        const std::string& s = *value.string;

        try {
            // Extra shenanigans to work around negative zero
            // conversion error in older GCC libs.
            if ( s[0] != '-' ) {
                return boost::lexical_cast<T>(s);
            } else {
                return -boost::lexical_cast<T>(s.substr(1));
            }
        } catch(const boost::bad_lexical_cast&) {
        }
        throw InvalidConversion(QPID_MSG("Cannot convert " << s));
                //Line 154
    }



Using the debugger to examine the value of s, shows that
convertFromString() is trying to convert the string 'amqp1.0' into an
int64.  The call to convertFromString() above, is made by the code below,
that seems to assume that if the datatype is a VAR_STRING, that a
lexical_cast will always be able to convert the text to a integer.

int64_t VariantImpl::asInt64() const
{
    switch(type) {
      case VAR_INT8: return value.i8;
      case VAR_INT16: return value.i16;
      case VAR_INT32: return value.i32;
      case VAR_INT64: return value.i64;
      case VAR_UINT8: return int64_t(value.ui8);
      case VAR_UINT16: return int64_t(value.ui16);
      case VAR_UINT32: return int64_t(value.ui32);
      case VAR_UINT64:
        if (value.ui64 <= (uint64_t) std::numeric_limits<int64_t>::max())
              return int64_t(value.ui64);
          break;
      case VAR_STRING: return convertFromString<int64_t>();
    //Called from here
      default: break;
    }
    throw InvalidConversion(QPID_MSG("Cannot convert from " <<
getTypeName(type) << " to " << getTypeName(VAR_INT64)));
}

It seems that this code-path is executed for each of the connection
options.  I'm guessing the exceptions raised by the boost::lexical_cast, is
causing the RELEASE version of the code to abort.

Please can someone who understands this piece of code in more detail assist
to resolve?

Kind regards,
Michael

Reply via email to