You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AVRO C++编码字符串时API崩溃问题求助

AVRO C++ 字符串编码崩溃问题

我是编程和AVRO的新手,尝试对字符串进行AVRO编码解码,完全按照Apache AVRO C++官方文档示例操作。

JSON Schema

{
    "type": "record",
    "name": "cpx",
    "fields" : [
        {"name": "re", "type": "string"},
        {"name": "im", "type" : "string"}
    ]
}

生成的头文件(bla.hh)

namespace c {
struct cpx {
    std::string re;
    std::string im;
    cpx() :
        re(std::string()),
        im(std::string())
        { }
};

}
namespace avro {
template<> struct codec_traits<c::cpx> {
    static void encode(Encoder& e, const c::cpx& v) {
        avro::encode(e, v.re);
        avro::encode(e, v.im);
    }
    static void decode(Decoder& d, c::cpx& v) {
        if (avro::ResolvingDecoder *rd =
            dynamic_cast<avro::ResolvingDecoder *>(&d)) {
            const std::vector<size_t> fo = rd->fieldOrder();
            for (std::vector<size_t>::const_iterator it = fo.begin();
                it != fo.end(); ++it) {
                switch (*it) {
                case 0:
                    avro::decode(d, v.re);
                    break;
                case 1:
                    avro::decode(d, v.im);
                    break;
                default:
                    break;
                }
            }
        } else {
            avro::decode(d, v.re);
            avro::decode(d, v.im);
        }
    }
};
}

CPP源码文件(test.cpp)

#include <stdlib.h>
#include "bla.hh"
#include "avro/Encoder.hh"
#include "avro/Decoder.hh"


int main()
{
    std::unique_ptr<avro::OutputStream> out = avro::memoryOutputStream();
    avro::EncoderPtr e = avro::binaryEncoder();
    e->init(*out);
    c::cpx c1;
    c1.re = "hello";
    c1.im = "thanks";
    avro::encode(*e, c1);

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

    c::cpx c2;
    avro::decode(*d, c2);
    std::cout << '(' << c2.re << ", " << c2.im << ')' << std::endl;
    std::cout << "DECODED" << std::endl;
    return 0;
}

编译命令

g++ test.cpp -std=c++11 -lavrocpp

崩溃信息

运行程序触发段错误,核心转储的GDB回溯如下:

#0  __memcpy_ssse3_back () at ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:896
#1  0x00007f28e9dad9e1 in avro::BinaryEncoder::encodeString(std::string const&) () from /usr/local/lib/libavrocpp.so.1.11.0
#2  0x0000000000401778 in avro::codec_traits<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >::encode(avro::Encoder&, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&) ()
#3  0x0000000000401a6e in void avro::encode<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >(avro::Encoder&, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&) ()
#4  0x0000000000401830 in avro::codec_traits<c::cpx>::encode(avro::Encoder&, c::cpx const&) ()
#5  0x0000000000401ddc in void avro::encode<c::cpx>(avro::Encoder&, c::cpx const&) ()
#6  0x00000000004014ac in main ()

问题原因

从回溯看,崩溃发生在avro::BinaryEncoder::encodeString调用memcpy时,核心原因是C++标准库ABI不兼容:

  • 程序用-std=c++11编译,启用了GCC的__cxx11版本std::string(C++11引入的新实现);
  • 系统中安装的libavrocpp.so.1.11.0可能是用旧标准(如C++03)或不同ABI编译的,导致AVRO库期望的std::string与程序中的std::string内存布局不一致,触发非法内存访问。

另外,编码完成后未调用e->flush(),虽不直接导致崩溃,但可能造成输出流数据不完整,引发后续解码问题。

解决方法

  1. 统一C++标准库ABI
    编译程序时添加-D_GLIBCXX_USE_CXX11_ABI=0,强制使用旧ABI匹配AVRO库:

    g++ test.cpp -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -lavrocpp
    

    或者重新编译AVRO库,使用-std=c++11启用新ABI,确保和程序编译选项一致。

  2. 添加编码器刷新操作
    在avro::encode(*e, c1);后添加e->flush();,确保所有数据写入输出流:

    avro::encode(*e, c1);
    e->flush(); // 新增该行
    
  3. 编译时添加调试信息
    编译时加上-g参数,方便后续排查问题:

    g++ test.cpp -std=c++11 -g -D_GLIBCXX_USE_CXX11_ABI=0 -lavrocpp
    

内容的提问来源于stack exchange,提问作者Dharmendra Koppineni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 02:48:21