QPID Client on Win10 aborts when connection object is created

2018-07-03 Thread Michael Arnold
Hi,

Still no luck with this one.  A couple more data points:

- I tried single stepping through the QPID code but never got to a trim()
routine.  I also ran the code in debug mode with a breakpoints set on any
routine called 'trim', with the code never breaking.  This led me to
conclude that the stack is just corrupted and thus gives no hint on where
the issue is actually arising.

- I carefully checked that I am using consistent versions of the .lib and
.dll files at compile time and run time.  Its all consistent.

- The QPID client example programs work fine, but when building the code
with my cmake file it produces an error at run time both with debug and
release builds.  With debug build I found that the exception is thrown when
the code execution returns to the line:
qpid::Options opts;
There is nothing obviously wrong with the code executed by this line when
single stepping into the statement in debug mode.  The exception that is
thrown is 'bad alloc'.

- I tried modifying my cmake file to make it more like the example
provided, but with no success.  Possibly the problem is because I'm
including Qt in my cmake file, or the fact that I'm creating the QPID
connection within a QRunnable, QObject.

Kind regards,
Michael


Re: QPID Client on Win10 aborts when connection object is created

2018-06-16 Thread Michael Arnold
Hi,

I had another go at getting a QPID client connection created with a Windows
10 Release version of QPID Messaging built using Proton.  I've concluded
that my earlier assumption that the abort() is being called because of
exceptions raised during connection option parsing is incorrect.  I
concluded that connection parsing exceptions are ok for two reasons:
- Spending sometime looking at the code and with the debugger, I'm
convinced that the exceptions being raised are as designed and the
exceptions themselves are handled.
- Rerunning the Release version of the code in the debugger gave the
following stack dump, which indicates the abort() is called later in the
code:

1  RaiseException
KERNELBASE0x7fffd9b1a388
2  CxxThrowException
VCRUNTIME140  0x7fffd5a143dd
3  qpid::messaging::amqp::EncodedMessage::trim
qpidmessaging 0x7fffb0bc7b1b
4  qpid::messaging::amqp::EncodedMessage::trim
qpidmessaging 0x7fffb0bc6e01
5  qpid::messaging::Address::getSubject
qpidmessaging 0x7fffb0b6640b
6  qpid::messaging::Sender::`default constructor closure'
qpidmessaging 0x7fffb0b7d4e5
7  qpid::messaging::Connection::Connection
qpidmessaging 0x7fffb0bb780d

From:

https://stackoverflow.com/questions/186237/program-only-crashes-as-release-build-how-to-debug#186285
It appears that a common reason for Release version of code to fail (and
not Debug version) is writing beyond the end of an local array variable
within a sub-routine - causing the stack unwind to crash (debug info on the
stack reduces the chance of this in Debug builds).

I've tried a couple of things, all without success:
- Trying to trace down into the trim() routine with a debug version to see
if I can spot any array handling irregularitities - but with all the
constructors at play, Im not able to find my way there with the debugger.
- Rebuild a Release version of QPID from git - no change.
- Compiling Proton / Qpid on Linux and checking with Valgrind for any
memory allocation / write mistakes - nothing found.
- Installing drmemory on windows to also chec for any memory allocation /
write mistakes - could not get drmemory to work.

Any thoughts / suggestions?

Kind regards,
Michael


On Mon, Jun 11, 2018 at 8:33 PM, Michael Arnold  wrote:

> 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.cpp50  0x7ff9f1ca3fd9
> 12  BasicConnection::BasicConnection
> ExternalInterface.cxx 51  0x7ff6e6661151
> 13  

QPID Client on Win10 aborts when connection object is created

2018-06-11 Thread Michael Arnold
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.cpp50  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
typename enable_if::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(s);
} else {
return -boost::lexical_cast(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::max())
  return int64_t(value.ui64);
  break;
  case VAR_STRING: return convertFromString();
//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