Search code examples
c++gdbc++17avro

Segmentation fault with c++17, but not c++11, with Apache Avro


UPDATE: So I found a post talking about Avro using an older standard c++11/14 here. I really don't understand what the commenter was talking about to make changes, but it was obvious that something in the Boost library, or the fact that avro wasn't using the boost library was the issue.

so I found the GenericDatum.hh file and took a closer look.

#if __cplusplus >= 201703L
    std::any value_;
#else
    boost::any value_;
#endif

It does appear that c++17 is viable for the latest avro. this indicates to me that it wants to use std::any for anything new than 201703L, which I take as c++17 or newer.

The comment in the post indicated you want to use boost. What am I missing?

ORIGINAL: So I'm working with Apache Avro serialization library. I'm attempting to understand it better by testing the examples it provides. that information can be found here.

Some of the examples work fine, but one issue I'm having is with the generic.cc file. When I compile the generic.cc example via the command line I have no issues. it runs just fine.

g++ generic.cc -lavrocpp -o test.exe

Because I'm using the c++17 standard in my main project, I went back and re-compiled the generic.cc file with c++17

g++ generic.cc -std=c++17 -lavrocpp -o test.exe

it compiles fine, yet throws a segmentation fault. So there's something with the example software that is not formatted properly for the c++17 standard.

I've run a debugger, gdb, and it spit out.

Program received signal SIGSEGV, Segmentation fault.
0x0000555555556e28 in avro::GenericDatum::GenericDatum(avro::GenericDatum const&) ()

So the GenericDatum is part of Avro, without attempting to make changes to the avro library, is there a way for me to use c++17?

as the code throws the segmentation fault at the GenericDatum initialization. The minimum code to reproduce is as follows.

#include <fstream>
#include <complex>

#include "cpx.hh"

#include "avro/Compiler.hh"
#include "avro/Encoder.hh"
#include "avro/Decoder.hh"
#include "avro/Specific.hh"
#include "avro/Generic.hh"

int
main()
{
    std::ifstream ifs("cpx.json");

    avro::ValidSchema cpxSchema;
    avro::compileJsonSchema(ifs, cpxSchema);

    std::unique_ptr<avro::OutputStream> out = avro::memoryOutputStream();
    avro::EncoderPtr e = avro::binaryEncoder();
    e->init(*out);
    c::cpx c1;
    c1.re = 100.23;
    c1.im = 105.77;
    avro::encode(*e, c1);

    std::unique_ptr<avro::InputStream> in = avro::memoryInputStream(*out);
    avro::DecoderPtr d = avro::binaryDecoder();
    d->init(*in);

    avro::GenericDatum datum(cpxSchema);

    return 0;
}

Solution

  • So with the help of @RichardCritten I was able to figure out how to fix my issue.

    As Richard mentioned in his comment above, I was linking to a pre-built library, which was built with c++11. What I ended up doing was looking through the build script and ultimately in the CMakeLists.txt file, I changed the CMAKE_CXX_STANDARD value from 11 to 17.

    Obviously, if it's not clear this is for the C++ build of Avro. When building the library for Avro you need to be located in the /Development/aphache_avro/avro-src-1.11.0/lang/c++ directory.

    Here you will find the build script build.sh and the CMakeLists.txt file it uses to configure and build the library. on lines 23-25, of CMakeLists.txt, you will be able to change from c++11 to c++17, simply by updating the 11 to 17. Once you do this you can rebuild with the command ./build test, which will first test the build for any errors, you can then build and install with the command sudo ./build.sh install.

    This allowed me to rebuild the library with c++17 standard and now I can build my own application linking with the Avro library and building with c++17.