Apache Avro C++ 段错误

问题描述 投票:0回答:1

我正在尝试使用 Avro C++ 库。我想创建一个 GenericDatum 实例,但使用以下代码时出现段错误。

avro_read.cc

#include <fstream>
#include <avro/GenericDatum.hh>
#include <avro/ValidSchema.hh>
#include <avro/Compiler.hh>

int main(int argc, char* argv[]) {
  // Read in and compile schema.
  std::ifstream in("schema.avsc");
  avro::ValidSchema valid_schema;
  avro::compileJsonSchema(in, valid_schema);

  // Create a generic datum (segfaults).
  avro::GenericDatum datum(valid_schema); 
  return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.20)

project(repro CXX)

find_package(unofficial-avro-cpp CONFIG REQUIRED)

add_executable(avro_read avro_read.cc)
target_link_libraries(avro_read PRIVATE unofficial::avro-cpp::avrocpp)

vcpkg.json

{
  "name": "segfault-repro",
  "version-string": "unversioned",
  "description": "A simple repro for the avro GenericDatum segfault",
  "dependencies": [
    "avro-cpp"
  ]
}

架构.avsc

{
    "type": "record",
    "name": "__root__",
    "fields": [
        {
            "name": "name",
            "type": [
                "null",
                "string"
            ]
        },
        {
            "name": "total",
            "type": [
                "null",
                "long"
            ]
        }
    ]
}

我使用 CMake 和 Vcpkg 进行编译以及以下命令:

cmake -S . -B .build -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_TOOLCHAIN_FILE=$HOME/vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build .build
.build/avro_read 

我尝试运行gdb(

gdb .build/avro_read
,但没有得到任何有用的东西

Program received signal SIGSEGV, Segmentation fault.
0x00005555555ecd70 in ?? ()
(gdb) bt
#0  0x00005555555ecd70 in ?? ()
#1  0x000055555556b46d in main ()

然后我就跑了

valgrind --leak-check=full .build/avro_read

==2398834== Memcheck, a memory error detector
==2398834== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==2398834== Using Valgrind-3.20.0 and LibVEX; rerun with -h for copyright info
==2398834== Command: .build/avro_read
==2398834== 
vex amd64->IR: unhandled instruction bytes: 0xF1 0x60 0x3E 0x0 0x0 0x0 0x0 0x0 0x10 0x7F
vex amd64->IR:   REX=0 REX.W=0 REX.R=0 REX.X=0 REX.B=0
vex amd64->IR:   VEX=0 VEX.L=0 VEX.nVVVV=0x0 ESC=NONE
vex amd64->IR:   PFX.66=0 PFX.F2=0 PFX.F3=0
==2398834== Invalid read of size 1
==2398834==    at 0x4DC7EC0: ???
==2398834==    by 0x4DC60DF: ???
==2398834==    by 0x7: ???
==2398834==  Address 0x1b is not stack'd, malloc'd or (recently) free'd
==2398834== 
==2398834== 
==2398834== Process terminating with default action of signal 11 (SIGSEGV)
==2398834==  Access not within mapped region at address 0x1B
==2398834==    at 0x4DC7EC0: ???
==2398834==    by 0x4DC60DF: ???
==2398834==    by 0x7: ???
==2398834==  If you believe this happened as a result of a stack
==2398834==  overflow in your program's main thread (unlikely but
==2398834==  possible), you can try to increase the size of the
==2398834==  main thread stack using the --main-stacksize= flag.
==2398834==  The main thread stack size used in this run was 8388608.
==2398834== 
==2398834== HEAP SUMMARY:
==2398834==     in use at exit: 84,688 bytes in 40 blocks
==2398834==   total heap usage: 123 allocs, 83 frees, 97,888 bytes allocated
==2398834== 
==2398834== LEAK SUMMARY:
==2398834==    definitely lost: 0 bytes in 0 blocks
==2398834==    indirectly lost: 0 bytes in 0 blocks
==2398834==      possibly lost: 0 bytes in 0 blocks
==2398834==    still reachable: 84,688 bytes in 40 blocks
==2398834==         suppressed: 0 bytes in 0 blocks
==2398834== Reachable blocks (those to which a pointer was found) are not shown.
==2398834== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==2398834== 
==2398834== For lists of detected and suppressed errors, rerun with: -s
==2398834== ERROR SUMMARY: 2 errors from 1 contexts (suppressed: 0 from 0)
[1]    2398834 segmentation fault  valgrind --leak-check=full .build/avro_read

更新:

avro 代码包含 any/boost any,具体取决于 C++ 版本。 https://github.com/apache/avro/blob/e932c9453be7b36e8874fe92edb3710beef4e47c/lang/c%2B%2B/api/GenericDatum.hh#L27-L31.

#if __cplusplus >= 201703L
#include <any>
#else
#include "boost/any.hpp"
#endif

当我使用 C++ 14 编译时,没有出现段错误:

set (CMAKE_CXX_STANDARD 14)

但是当我使用 C++ 17 或 C++20 时,我会出现段错误

set (CMAKE_CXX_STANDARD 17)

我认为

any_cast
之一是在 nullptr 和段错误上调用的。

c++ memory segmentation-fault avro
1个回答
0
投票

我将使用 C++ 14,它编译时不会出现段错误。

© www.soinside.com 2019 - 2024. All rights reserved.