我正在尝试使用 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++ 14,它编译时不会出现段错误。