Skip to content

Linking debug .dll (via vcpkg) to debug build of windows app causes string corruption issues #1465

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
whenpiqsfly opened this issue Feb 8, 2023 · 1 comment

Comments

@whenpiqsfly
Copy link

whenpiqsfly commented Feb 8, 2023

Describe the bug
[updated] - i made some progress on uncovering the root cause; updated title and description to reflect my current understanding

When linking the debug .dll and .lib (generated via vcpkg) to debug build of an Visual C++ project, any string assignment from a jsoncpp library function to the main app (also in debug mode) will cause garbage to be written and crash the app.

I believe this is due to a mismatch linking CRT between the library and the app. I can reproduce a similar behavior with other libraries (such as, say, libcurl) by linking the release version of the dll against debug build of the app. Stack Overflow has a nice explanation.

To Reproduce

  • install jsoncpp 1.9.5 via vcpkg on windows .\vcpkg.exe install jsoncpp:x64-windows
  • create simple .exe application that outputs json string, linking to the debug .lib and .dll files. I tried both with StreamWriterBuilder and FastWriter.
#include <json/json.h>
#include <iostream>

int main(int argc, char* argv[])
{
	Json::Value payloadJson;
	payloadJson["foo"] = "bar";
	
	Json::StreamWriterBuilder builder;
	builder["indentation"] = "";
	std::string output = Json::writeString(builder, payloadJson);
	//Json::FastWriter writer;
	//std::string output = writer.write(payloadJson);

	std::cout << output;

	return 0;
}
  • with StreamWriterBuilder, it crashes on assigning indentation string:
Exception thrown at 0x00007FFA8C6F1490 (vcruntime140.dll) in jsoncpptest.exe: 0xC0000005: Access violation reading location 0x000000565D9E6871.

vcruntime140.dll!00007ffa8c6f1490()
[Inline Frame] jsoncpp.dll!Json::duplicateStringValue(const char * value, unsigned __int64) Line 126
	at C:\Users\david\src\vcpkg\buildtrees\jsoncpp\src\1.9.5-13b47286ba.clean\src\lib_json\json_value.cpp(126)
jsoncpp.dll!Json::Value::CZString::CZString(const Json::Value::CZString & other) Line 247
	at C:\Users\david\src\vcpkg\buildtrees\jsoncpp\src\1.9.5-13b47286ba.clean\src\lib_json\json_value.cpp(247)
[Inline Frame] jsoncpp.dll!std::pair<Json::Value::CZString const ,Json::Value>::{ctor}(Json::Value::CZString & _Val2, const Json::Value &) Line 172
	at C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\utility(172)
jsoncpp.dll!Json::Value::resolveReference(const char * key, const char * end) Line 1069
	at C:\Users\david\src\vcpkg\buildtrees\jsoncpp\src\1.9.5-13b47286ba.clean\src\lib_json\json_value.cpp(1069)
jsoncpptest.exe!main(int argc, char * * argv) Line 10
	at C:\Users\david\src\jsoncpptest\main.cpp(10)
  • with FastWriter it crashes when write() returns NULL instead of the string.
  • I can confirmed that the JSON value contains the expected information.

Expected behavior
The same code works as expected on OSX.

Desktop

  • OS: Windows 10 Pro 21H2
  • Visual C++ 2022 (Visual Studio 17.4.4)
@whenpiqsfly whenpiqsfly changed the title jsoncpp_1.9.5_x64-windows (via vcpkg) string manipulation issues jsoncpp_1.9.5_x64-windows (via vcpkg) string assignment issues Feb 8, 2023
@whenpiqsfly whenpiqsfly changed the title jsoncpp_1.9.5_x64-windows (via vcpkg) string assignment issues Linking debug .dll (via vcpkg) to debug build of windows app causes string corruption issues Feb 9, 2023
@totszwai
Copy link

I think I might be facing a similar issue.

I have a dump function to print my JSON object for my own debugging purposes.

std::string dump(bool pretty = true) const
{
    Json::StreamWriterBuilder fmt;
    fmt["indentation"] = pretty ? "  " : "";
    std::string result = Json::writeString(fmt, *this);
    return result + "\n";
}

For simplicity, I stored an int into the JSON object.

rowdata["id"] = 1;
// if i call my dump function, I can longer access the member
// log(rowdata.dump());
log(rowdata["id"]);

Is this related?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants