log4cplus- helpers::towstring() and PropertyConfigurator::doConfigure scramble string parameter in C++/CLI running in non-CLR mode for x64 - c++-cli

I'm using log4cplus as a logger for both CLR and non-CLR C++/CLI code and C# code so for that reason I'm using the Unicode x64 build of log4cplus, log4cplusU.lib/dll.
If I run the following code in a non-CLR C++/CLI x64 console application, I get a memory access exception.
int _tmain(int argc, _TCHAR* argv[])
{
std::string LogFileName = "log4cplus.log";
auto db = log4cplus::helpers::towstring(LogFileName);
Exception:
Unhandled exception at 0x00007FF8E4A1CDA1 (msvcr120.dll) in ConsoleApplication1.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
What's up?
I'm using Visual Studio 2013. My call stack at the exception looks like:
> log4cplusU.dll!std::vector<wchar_t,std::allocator<wchar_t> >::vector<wchar_t,std::allocator<wchar_t> >(unsigned __int64 _Count) Line 691 C++
log4cplusU.dll!log4cplus::helpers::towstring_internal(std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > & outstr, const char * src, unsigned __int64 size, const std::locale & loc) Line 70 C++
log4cplusU.dll!log4cplus::helpers::towstring(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & src) Line 124 C++
ConsoleApplication1.exe!wmain(int argc, wchar_t * * argv) Line 24 C++
ConsoleApplication1.exe!__tmainCRTStartup() Line 623 C
At the point where the exception fires in std::vector(size_type), _Count is a crazy number.
_Count 14757396612626683276 unsigned __int64
The reason appears to be that the string parameter gets scrambled or misinterpreted.
The same problem manifests itself on non-Unicode DEBUG MODE builds of log4cplus in unmanaged code on VS but not in release mode builds.
For example:
#include <string>
#include "stdafx.h"
#include <iostream>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/configurator.h>
int _tmain(int argc, _TCHAR* argv[])
{
std::string LogConfigFileName = "WhenLoggingCppManagedCode.properties";
try
{
log4cplus::tstring cfn = LogConfigFileName;
log4cplus::PropertyConfigurator::doConfigure(cfn);
std::cout << "Good Deadpool." << std::endl;
}
catch (...)
{
std::cout << "BAD Deadpool." << std::endl;
}
std::cin.get();
return 0;
}

Related

How to set different decimal places in same rapidjson document

I have made a rapidjson document with all my objects and values using usual AddMember() method. Now I want to get the string out of that document for publishing to a mqtt broker. But inside that string, some members shall have 2 decimal places, some only one, and others all decimals.
I don't find how to set decimal place for a specific member after the document was fully builded.
I succeeded to do so by building my json document with a writer but this is not what i want to do because this document can't be easily modified:
#include <string>
#include <iostream>
#include <sstream>
#include <rapidjson/document.h> // rapidjson's DOM-style API
#include <rapidjson/prettywriter.h> // for stringify JSON
#include <rapidjson/stringbuffer.h>
using namespace rapidjson;
using namespace std;
int main (int argc, char* argv[])
{
Document doc;
StringBuffer buffer;
Writer<StringBuffer> writer(buffer);
writer.StartObject();
writer.Key("member1");
writer.SetMaxDecimalPlaces(2);
writer.Double(1.0000001);
writer.Key("member2");
writer.SetMaxDecimalPlaces(3);
writer.Double(3.123456);
writer.Key("member3");
writer.SetMaxDecimalPlaces(8);
writer.Double(2.123456);
writer.EndObject();
cout << buffer.GetString() << endl;
return 0;
}
./decimal
{"member1":1.0,"member2":3.123,"member3":2.123456}
Now, this how i build my document:
#include <string>
#include <iostream>
#include <sstream>
#include <rapidjson/document.h> // rapidjson's DOM-style API
#include <rapidjson/prettywriter.h> // for stringify JSON
#include <rapidjson/stringbuffer.h>
using namespace rapidjson;
using namespace std;
int main (int argc, char* argv[])
{
Document doc;
Document::AllocatorType& allocator = doc.GetAllocator();
StringBuffer buffer;
Writer<StringBuffer> writer(buffer);
doc.SetObject();
doc.AddMember("member1", 1.0000001, allocator);
doc.AddMember("member3", 3.123456, allocator);
doc.AddMember("member2", 2.123456, allocator);
writer.SetMaxDecimalPlaces(2);
doc.Accept(writer);
cout << buffer.GetString() << endl;
return 0;
}
./decimal
{"member1":1.0,"member2":2.12,"member3":3.12}
The SetMaxDecimalPlaces() applies to the whole document this way
I would like to get same output has first code example but using document made from second source code. How can i tell the writer to format each member differently ?
I'm super late to the party, but you can create a second writer with different writing settings:
StringBuffer buffer;
Writer<StringBuffer> writer1(buffer); // original writer
Writer<StringBuffer> writer2(buffer); // a new second writer
writer1.SetMaxDecimalPlaces(1);
writer2.SetMaxDecimalPlaces(2);
and then use the specific writers to write directly into the buffer instead of using the doc to call the writer:
writer.Key("member1");
writer.Double(1.0);
writer2.Key("member2");
writer2.Double(2.12);
writer2.Key("member3");
writer2.Double(3.12);
Full example:
using namespace rapidjson;
using namespace std;
int main (int argc, char* argv[])
{
StringBuffer buffer;
Writer<StringBuffer> writer1(buffer);
Writer<StringBuffer> writer2(buffer);
writer1.SetMaxDecimalPlaces(2);
writer2.SetMaxDecimalPlaces(2);
writer1.StartObject();
writer1.Key("member1");
writer1.Double(1.0);
writer2.Key("member2");
writer2.Double(2.12);
writer2.Key("member3");
writer2.Double(3.12);
writer1.EndObject();
cout << buffer.GetString() << endl;
return 0;
}

GetProcAddress returning the correct address with Visual C++ and an incorrect address with g++

This is going to sound really strange. I am using Visual Studio 2017 C++ (native mode) and also, g++ 4.7.1-2 of the MingW toolchain. Target is Windows 64bit.
Using VS C++, I compile the following trivial program:
`
#include "stdafx.h"
#include <Windows.h>
#include <winternl.h>
typedef NTSTATUS (NTAPI* RTLINT64)(ULONGLONG, ULONG, PUNICODE_STRING);
RTLINT64 RtlInt64 = (RTLINT64) nullptr;
int main()
{
UNICODE_STRING unicodestring = { 0 };
WCHAR localbuffer[256] = { 0 }; // way more than enough
__int64 value = 0;
unicodestring.Length = 0;
unicodestring.MaximumLength = sizeof(localbuffer);
unicodestring.Buffer = (PWCH) &localbuffer;
// get ntdll's module handle
HMODULE NtDllModule = LoadLibrary(L"ntdll.dll");
if (NtDllModule)
{
RtlInt64 = (RTLINT64) GetProcAddress(NtDllModule,
"RtlInt64ToUnicodeString");
value = 0xFFFFFFFFF;
RtlInt64 (value, 10, &unicodestring);
wprintf(L"%s\n", unicodestring.Buffer);
}
return 0;
}
`
As expected, GetProcAddress returns the address of RtlInt64ToUnicodeString (no surprise there!)
The code below is, with exception of the includes, pretty much a carbon copy of the above. Yet, somehow, in that version compiled with G++, GetProcAddress returns the address of RtlInterlockedSetBitRun instead of the address of RtlInt64ToUnicodeString (that IS a surprise!). Here is the code:
// GCC and MingW version
#include <Windows.h>
#include <winbase.h>
#include <strsafe.h>
#include <winuser.h>
#include <winternl.h>
// --------------------------------------------------------------------------
typedef NTSTATUS(NTAPI* RTLINT64)(ULONGLONG, ULONG, PUNICODE_STRING);
RTLINT64 RtlInt64 = (RTLINT64) nullptr;
// --------------------------------------------------------------------------
int main(int argc, char *argv[])
{
WCHAR localbuffer[256] = {0}; // way more than enough
UNICODE_STRING unicodestring = {0};
__int64 value = 0;
unicodestring.Length = 0;
unicodestring.MaximumLength = sizeof(localbuffer);
unicodestring.Buffer = (PWCH) &localbuffer;
// get ntdll's module handle
HMODULE NtDllModule = LoadLibraryW(L"ntdll.dll");
if (NtDllModule)
{
RtlInt64 = (RTLINT64) GetProcAddress(NtDllModule,
"RtlInt64ToUnicodeString");
// the above call to GetProcAddress returned the address of
// RtlInterlockedSetBitRun instead of the address of the requested function
// as a result, the statements below don't work.
value = 0xFFFFFFFFF;
RtlInt64(value, 10, &unicodestring);
wprintf(L"%s\n", unicodestring.Buffer);
}
return 0;
}
my question is: is there something in the above code that justifies the discrepancy ?
Also note that, I am using G++ with a tool called VisualGDB which integrates the compiler and the debugger into Visual Studio. Normally things of that kind can cause strange "side effects" but, in this case, it seems rather unlikely for something that has nothing to do with ntdll to be the culprit.
Thank you for your help.

Why do I need separable compilation?

I have the code shown below. As far as I understood, separable compilation must be turned on when
CUDA device code is separated into .h and .cu files
Use ObjectA's device code into Object's B device code
however, in my main function I am not having any of the cases above. Could you tell me why do I have to set separable compilation for this sample project?
BitHelper.h
#pragma once
#include <cuda_runtime.h>
#define COMPILE_TARGET __host__ __device__
class BitHelper
{
public:
COMPILE_TARGET BitHelper();
COMPILE_TARGET ~BitHelper();
COMPILE_TARGET static void clear(unsigned int& val0);
};
BitHelper.cu
#include "bithelper.h"
BitHelper::BitHelper()
{}
BitHelper::~BitHelper()
{}
void BitHelper::clear(unsigned int& val0)
{
val0 = 0x0000;
}
Consume_BitHelper.h
#pragma once
class Consume_BitHelper
{
public:
void apply();
private:
bool test_cpu();
bool test_gpu();
};
Consume_BitHelper.cu
#include "consume_bithelper.h"
#include <cuda_runtime.h>
#include <iostream>
#include "bithelper.h"
__global__
void myKernel()
{
unsigned int FLAG_VALUE = 0x2222;
printf("GPU before: %d\n", FLAG_VALUE);
BitHelper::clear(FLAG_VALUE);
printf("GPU after: %d\n", FLAG_VALUE);
}
void Consume_BitHelper::apply()
{
test_cpu();
test_gpu();
cudaDeviceSynchronize();
}
bool Consume_BitHelper::test_cpu()
{
std::cout << "TEST CPU" << std::endl;
unsigned int FLAG_VALUE = 0x1111;
std::cout << "CPU before: " << FLAG_VALUE << std::endl;
BitHelper::clear(FLAG_VALUE);
std::cout << "CPU after : " << FLAG_VALUE << std::endl;
return true;
}
bool Consume_BitHelper::test_gpu()
{
std::cout << "TEST GPU" << std::endl;
myKernel << <1, 1 >> > ();
return true;
}
main.cu
#include "consume_bithelper.h"
#include "bithelper.h"
#include <iostream>
int main(int argc, char** argv)
{
Consume_BitHelper cbh;
cbh.apply();
std::cout << "\nPress any key to continue...";
std::cin.get();
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(cuda_class LANGUAGES CXX CUDA)
#BitHelper needs separable compilation because we have separated declaration from definition
add_library(bithelper_lib STATIC bithelper.cu)
set_property(TARGET bithelper_lib PROPERTY CUDA_SEPARABLE_COMPILATION ON)
#Consume_BitHelper needs separable compilation because we call BitHelper's device code
#from Consume_BitHelper's kernel
add_library(consume_bithelper_lib STATIC consume_bithelper.cu)
set_property(TARGET consume_bithelper_lib PROPERTY CUDA_SEPARABLE_COMPILATION ON)
target_link_libraries(consume_bithelper_lib bithelper_lib)
#We only call CPU code so no need of separable compilation?
add_executable(${PROJECT_NAME} main.cu)
target_link_libraries(${PROJECT_NAME} bithelper_lib consume_bithelper_lib)
The errors I'm getting are these
EDIT
According to Robert Crovella's post Consume_BitHelper.cu uses BitHelper::clear defined in a separate compilation unit.
Does it mean I have to activate only separate compilation for BitHelper?
Since separate compilation has to do only with device code called from device code.
Why am I getting the mentioned errors when separate compilation is NOT on for cuda_class? (which is the executable created from CMake and is not calling any device code)
Separable compilation has to do with how the compiler handles function calls. In exchange for a little bit of overhead, you get the ability to make true function calls and thus access code from other "compilation units" (i.e. .cu source files).
As GPU programmers are obsessed with performance (particularly the extra registers that get used when separable compilation is enabled) Nvidia made it an option instead of default.
You should only need separable compilation for .cu files that access functions/globals defined in other .cu files.

Does the Accellera SystemC Implementation incorrectly implement to_long()?

Consider the following SystemC code:
#include <iostream>
#include "systemc.h"
using namespace std;
int
sc_main(int argc, char* argv[])
{
sc_bv<3> foo;
operand_0 = "0d6";
cout << foo.to_long() << endl; // prints -2
return EXIT_SUCCESS;
}
This prints out -2 rather than 6 as I would have expected. The apparent reason for doing so would be that to_long() interprets the bit-vector 0b110 as signed. However, in IEEE Std 1666-2011, it says in Section 7.2.9 referring to integer conversion functions such as to_long():
These member functions shall interpret the bits within a SystemC integer,
fixed-point type or vector, or any part-select or concatenation thereof,
as representing an unsigned binary value, with the exception of signed
integers and signed fixed-point types.
Do I misunderstand something or is the SystemC implementation from Accellera not adhering to the standard in this aspect?
I think you are correct, there does seems to be a discrepancy between the SystemC LRM (IEEE Std 1666-2011) and the implementation.
If you want foo to be interpreted as an unsigned value, you must use to_ulong():
#include <iostream>
#include <systemc>
using namespace std;
int sc_main(int argc, char* argv[]) {
sc_bv<3> foo("0d6");
cout << foo.to_long() << endl; // prints -2
cout << foo.to_ulong() << endl; // prints 6
return EXIT_SUCCESS;
}

QT 5.0 QDebug compilation error

I am having trouble compiling my code with QDebug, but i really need it.
#include <QCoreApplication>
#include <QtDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QDebug() << "hello";
return a.exec();
}
This is an example of the error i got on this simple test:
no matching function for call to 'QDebug::QDebug()'
Try this:
qDebug() << "hello";
The problem here is that QDebug does not have a default constructor. QDebug() << "hello"; would work if it did have one.
These are the available constructors:
QDebug(QIODevice* device);
QDebug(QString* string);
QDebug(QtMsgType type);
// and the copy constructor of course.
duDE's answer gives you what you're looking for.
For version 5.15 of Qt following worked for me,
add include file,
#include <QDebug>
and use,
qDebug() << "Your debug message.";