I am blocking on a problem I have tried to resolve for 2 days now..
I want to use rapidjson along with libpqxx/pistache to insert/read json data from an API call / from the database. I tried a simple version of the serialize example just to get hang of it, but it throws a seg fault..
On linux mint 19 (Tara), I complied my code (I put the relevant code in main.cc) using CMake/Make and C++17.
Here is the folder tree:
/home/[user]/Documents/algoEngine/library/sources/main.cc /home/[user]/Documents/algoEngine/library/sources/library.cc /home/[user]/Documents/algoEngine/library/headers/library.hh /usr/local/include/rapidjson /usr/local/lib/libpqxx.so /usr/local/lib/libpistache.so
My CMakeLists.txt file:
cmake_minimum_required(VERSION 3.10.2)
project(algoEngine)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# fmax-errors => max number of errors displayed at compile time
# GCC_COMPILE_FLAGS = can append several desired option of gcc. For example: "-fmax-errors=3 -Wall"
set(GCC_COMPILE_FLAGS "-fmax-errors=3 -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COMPILE_FLAGS}")
# adding preprocessor values..
add_compile_definitions(RAPIDJSON_HAS_STDSTRING=1)
#However, the file(GLOB...) allows for wildcard additions:
file(GLOB SOURCES_LIBRARY "${CMAKE_SOURCE_DIR}/library/sources/*.cc")
# remove libraryBridge.cc from SOURCES_LIBRARY
list(REMOVE_ITEM SOURCES_LIBRARY "${CMAKE_SOURCE_DIR}/library/sources/libraryBridge.cc")
add_executable(algoLibrary ${SOURCES_LIBRARY})
target_include_directories(algoLibrary PUBLIC ${CMAKE_SOURCE_DIR}/library/headers) # might be useless with find_package just below?
find_package(RapidJSON)
target_link_libraries(algoLibrary pistache pqxx)
set(CMAKE_INSTALL_RPATH "/usr/local/lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
######################## INSTALL CONFIGURATION ########################
# create conf directory
set(algoLibraryInstallDir "/usr/local/bin/algoLibrary")
file(GLOB algoLibraryConfFiles "${CMAKE_SOURCE_DIR}/library/conf/*Library*.conf")
install(TARGETS algoLibrary DESTINATION ${algoLibraryInstallDir})
install(FILES ${algoLibraryConfFiles} DESTINATION ${algoLibraryInstallDir}/conf)
My main.cc file (I modified the file to only have the test I want. Normally, I would instantiate a "Library" class which contains a http server with Pistache)
#include "library.hh"
// for test purpose, to remove..
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/writer.h"
using namespace std;
using namespace rapidjson;
int main(int argc, char* argv[]) {
const char* json = "{\"address\":\"127.0.0.1\", \"port\":9100}";
Document doc;
doc.Parse(json);
StringBuffer jsonBuffer;
Writer<StringBuffer> jsonWriter;
doc.Accept(jsonWriter);
std::cout << "output json is : " << jsonBuffer.GetString() << endl;
return 0;
}
The program goes into segmentation fault when I execute it. I tried executing with GDB, here is the output:
gdb /usr/local/bin/algoLibrary/algoLibrary
... Reading symbols from
/usr/local/bin/algoLibrary/algoLibrary...done. (gdb) b main Breakpoint 1 at 0x2ad46: file
/home/farouk/Documents/algoEngine/library/sources/main.cc, line 11.
(gdb) r
Starting program: /usr/local/bin/algoLibrary/algoLibrary
[Thread debugging using libthread_db enabled] Using host libthread_db
library "/lib/x86_64-linux-gnu/libthread_db.so.1".
n
Breakpoint 1, main (argc=1, argv=0x7fffffffe468) at
/home/farouk/Documents/algoEngine/library/sources/main.cc:11 11 int main(int argc, char* argv[]) {
(gdb) n
28 const char* json =
"{\"address\":\"127.0.0.1\", \"port\":9100}";
(gdb)
29 Document doc;
(gdb)
30 doc.Parse(json);
(gdb)
32 StringBuffer jsonBuffer;
(gdb)
33 Writer<StringBuffer> jsonWriter;
(gdb)
35
doc.Accept(jsonWriter); (gdb)
Program received signal SIGSEGV, Segmentation fault.
0x000055555556e2d0 in
rapidjson::internal::Stack<rapidjson::CrtAllocator>::Reserve<char>
(this=0x0, count=1) at
/usr/local/include/rapidjson/internal/stack.h:118 118 if(RAPIDJSON_UNLIKELY(static_cast<std::ptrdiff_t>(sizeof(T) * count) (stackEnd_ - stackTop_)))
Ok I finally found my problem by comparing my code line by line with the example in rapidjson/example/serialize/serialize.cpp:
when instantiating a rapidjson::Writer (or PrettyWritter), you need to call its constructor with the StringBuffer as argument. My code would then become:
int main(int argc, char* argv[]) {
const char* json = "{\"address\":\"127.0.0.1\", \"port\":9100}";
Document doc;
doc.Parse(json);
StringBuffer jsonBuffer;
Writer<StringBuffer> jsonWriter(jsonBuffer); // Update is here: give jsonBuffer to jsonWriter
doc.Accept(jsonWriter);
std::cout << "output json is : " << jsonBuffer.GetString() << endl;
return 0;
}