Skip to content

Commit 1f7fdb8

Browse files
Fix MessageId::getDataAsString() crashed with MSVC debug config (#108)
Fixes #107 ### Motivation The `MessageId::getDataAsString()` API returns a `std::string` to the application side. In most cases it's not an issue. However, when building Windows DLLs with `LINK_STATIC=ON`, the library will be built with `/MTd` or `/MT` option to link 3rd party dependencies statically. In this case, the DLL and the application have different C runtime libraries that allocate or deallocate memory. The returned `std::string` object is allocated inside the DLL, while it will be destroyed in the application. The destruction could crash because the application C runtime cannot find the heap address from the C runtime in DLL. ### Modifications For MSVC debug build, change the API to return a const reference to `std::string`. Then the original `std::string` object will be deallocated inside the DLL.
1 parent 74ef1a0 commit 1f7fdb8

File tree

2 files changed

+15
-0
lines changed

2 files changed

+15
-0
lines changed

include/pulsar/Message.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,15 @@ class PULSAR_PUBLIC Message {
9090
* Get string representation of the message
9191
*
9292
* @return the string representation of the message payload
93+
*
94+
* NOTE: For MSVC with debug mode, return a thread local std::string object to avoid memory allocation
95+
* across DLLs and applications, which could lead to a crash.
9396
*/
97+
#if defined(_MSC_VER) && !defined(NDEBUG)
98+
const std::string& getDataAsString() const;
99+
#else
94100
std::string getDataAsString() const;
101+
#endif
95102

96103
/**
97104
* Get key value message.

lib/Message.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,15 @@ const void* Message::getData() const { return impl_->payload.data(); }
5454

5555
std::size_t Message::getLength() const { return impl_->payload.readableBytes(); }
5656

57+
#if defined(_MSC_VER) && !defined(NDEBUG)
58+
const std::string& Message::getDataAsString() const {
59+
thread_local std::string value;
60+
value = std::string{static_cast<const char*>(getData()), getLength()};
61+
return value;
62+
}
63+
#else
5764
std::string Message::getDataAsString() const { return std::string((const char*)getData(), getLength()); }
65+
#endif
5866

5967
Message::Message() : impl_() {}
6068

0 commit comments

Comments
 (0)