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

Apache Arrow C++读取CSV示例触发Segmentation Fault求助

排查Apache Arrow C++读取CSV时的段错误问题

我来帮你分析这个段错误的问题,看代码和Core Dump信息,很快就能找到根源:

问题相关信息

环境信息

  • g++版本:7.3.1
  • 编译命令:c++ -g -std=c++11 -Wall -O2 test.cpp -o test -I../../arrow/src -L../../arrow/lib -larrow -lparquet -Wl,-rpath,./

问题代码片段

arrow::Status status;
arrow::MemoryPool *pool = arrow::default_memory_pool();
std::shared_ptr<arrow::io::InputStream> input;
std::string csv_file = "test.csv";
auto input_readable = std::dynamic_pointer_cast<arrow::io::ReadableFile>(input);
PARQUET_THROW_NOT_OK(arrow::io::ReadableFile::Open(csv_file, pool, &input_readable));
auto read_options = arrow::csv::ReadOptions::Defaults();
read_options.use_threads = false;
read_options.column_names.emplace_back("name");
read_options.column_names.emplace_back("age");
auto parse_options = arrow::csv::ParseOptions::Defaults();
auto convert_options = arrow::csv::ConvertOptions::Defaults();
convert_options.include_missing_columns = true;
std::shared_ptr<arrow::csv::TableReader> reader;
status = arrow::csv::TableReader::Make(pool, input, read_options, parse_options, convert_options, &reader);
if (!status.ok()) {
    std::cout << "make csv table error" << std::endl;
    return -1;
}
std::shared_ptr<arrow::Table> table;
status = reader->Read(&table);
if (!status.ok()) {
    std::cout << "read csv table error" << std::endl;
    return -1;
}

Core Dump信息

Program terminated with signal 11, Segmentation fault.
#0 0x00007fe4fcda83e7 in arrow::io::internal::ReadaheadSpooler::Impl::WorkerLoop() () from ./libarrow.so.15
(gdb) bt
#0 0x00007fe4fcda83e7 in arrow::io::internal::ReadaheadSpooler::Impl::WorkerLoop() () from ./libarrow.so.15
#1 0x00007fe4fd405a2f in execute_native_thread_routine () from ./libarrow.so.15
#2 0x00007fe4fa8ecdf3 in start_thread () from /lib64/libpthread.so.0
#3 0x00007fe4fb86e1bd in clone () from /lib64/libc.so.6

CSV文件内容

name,age
aaa,12
bbb,13
ccc,14
ddd,15

问题根源

你代码里的核心错误是:创建TableReader时传入的是未初始化的空指针input,而不是你实际打开的文件流input_readable。

具体来说:

  1. 你先初始化了一个空的std::shared_ptr<arrow::io::InputStream> input;
  2. 然后把这个空指针转成input_readable,接着调用ReadableFile::Open成功打开了文件,此时input_readable指向了有效的文件句柄,但input本身还是空的
  3. 最后创建TableReader时,你传入了空的input,导致Arrow内部尝试读取数据时访问了空指针,触发了段错误——哪怕你设置了use_threads = false,Arrow的预读机制还是会尝试操作这个无效的流,所以崩溃在了ReadaheadSpooler的线程逻辑里。

修复方案

调整代码逻辑,确保传入TableReader的是已经打开的有效文件流:

arrow::Status status;
arrow::MemoryPool *pool = arrow::default_memory_pool();
std::string csv_file = "test.csv";

// 直接初始化ReadableFile,跳过空的InputStream初始化
std::shared_ptr<arrow::io::ReadableFile> input_readable;
PARQUET_THROW_NOT_OK(arrow::io::ReadableFile::Open(csv_file, pool, &input_readable));
// 将ReadableFile转换为InputStream类型(TableReader需要这个接口)
std::shared_ptr<arrow::io::InputStream> input = input_readable;

auto read_options = arrow::csv::ReadOptions::Defaults();
read_options.use_threads = false;
// 因为你的CSV已经有表头了,其实可以去掉下面两行,让Arrow自动解析列名
// read_options.column_names.emplace_back("name");
// read_options.column_names.emplace_back("age");
auto parse_options = arrow::csv::ParseOptions::Defaults();
auto convert_options = arrow::csv::ConvertOptions::Defaults();
convert_options.include_missing_columns = true;

std::shared_ptr<arrow::csv::TableReader> reader;
// 这里传入有效的input流
status = arrow::csv::TableReader::Make(pool, input, read_options, parse_options, convert_options, &reader);
if (!status.ok()) {
    std::cout << "make csv table error: " << status.ToString() << std::endl;
    return -1;
}

std::shared_ptr<arrow::Table> table;
status = reader->Read(&table);
if (!status.ok()) {
    std::cout << "read csv table error: " << status.ToString() << std::endl;
    return -1;
}

// 可以加个验证,确认读取成功
std::cout << "Successfully read " << table->num_rows() << " rows" << std::endl;

额外提示

  • 你的CSV文件第一行已经是列名,完全不需要手动设置read_options.column_names,让Arrow自动解析表头会更灵活,避免硬编码列名带来的维护问题
  • 建议在打印错误时加上status.ToString(),这样能看到更具体的错误信息,方便后续排查

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:32:52