medical_SDK/log/SEGMENTATION_FAULT_DEBUG.md

4.5 KiB
Raw Permalink Blame History

段错误诊断指南

常见段错误原因

1. 空指针访问

// 危险:没有检查指针是否为空
auto& input_channels = std::get<std::vector<std::vector<float>>>(data.channel_data);

// 安全先检查variant状态
if (data.channel_data.valueless_by_exception()) {
    throw std::runtime_error("Channel data is in invalid state");
}

2. 数组越界

// 危险:直接访问数组元素
for (int i = 0; i < 8; ++i) {
    output_channels[i] = input_channels[i]; // 可能越界
}

// 安全:先检查数组大小
if (input_channels.size() < 8) {
    throw std::runtime_error("Not enough channels");
}

3. 空容器访问

// 危险:访问空容器
if (!input_channels.empty()) {
    auto min_val = *std::min_element(input_channels[0].begin(), input_channels[0].end());
}

// 安全:检查容器是否为空
if (!input_channels.empty() && !input_channels[0].empty()) {
    auto min_val = *std::min_element(input_channels[0].begin(), input_channels[0].end());
}

已修复的问题

1. MAPPER函数增强安全检查

  • 添加了valueless_by_exception()检查
  • 验证输入通道是否为空
  • 检查每个通道是否有数据
  • 提供详细的错误信息

2. Main函数增强调试功能

  • 添加了debug_channel_data()函数
  • 在每个处理阶段显示数据状态
  • 使用try-catch包装每个映射操作
  • 提供详细的处理进度信息

调试步骤

步骤1运行测试模式1

请选择测试模式:
1. 测试新解析函数 (查看解析结果)
2. 运行原有测试流程
请输入选择 (1 或 2): 1

目的: 验证解析器是否正常工作

步骤2检查解析结果

  • 查看每个数据对象的详细信息
  • 确认通道数据格式正确
  • 验证采样点数合理

步骤3运行测试模式2

请输入选择 (1 或 2): 2

目的: 逐步执行完整流程,定位问题

步骤4观察调试输出

=== 调试信息: 解析后 ===
数据类型: ECG_12LEAD (12导联心电)
包序号: 0
时间戳: 1234567890
多通道数据: 8 个通道
  通道 0: 42 个采样点 [范围: -1.25 ~ 1.45]
  通道 1: 42 个采样点 [范围: -0.98 ~ 1.23]
  ...
原始数据大小: 1234 字节
================================

常见问题排查

问题1解析器返回空数据

症状: 所有通道都是空的 可能原因:

  • 文件路径错误
  • 文件格式不匹配
  • 解析逻辑错误

解决方案:

// 检查文件是否存在
if (file_content.empty()) {
    throw std::runtime_error("File is empty or cannot be read");
}

// 检查文件大小
std::cout << "文件大小: " << file_content.size() << " 字节" << std::endl;

问题2通道数量不匹配

症状: 期望8个通道但只有3个 可能原因:

  • 设备类型识别错误
  • 数据包不完整
  • 解析逻辑有bug

解决方案:

// 在MAPPER中添加详细检查
if (input_channels.size() < expected_channels) {
    std::string error_msg = "Expected " + std::to_string(expected_channels) + 
                           " channels, but got " + std::to_string(input_channels.size());
    throw std::runtime_error(error_msg);
}

问题3通道数据为空

症状: 通道存在但采样点数为0 可能原因:

  • 数据包损坏
  • 解析偏移错误
  • 数据类型不匹配

解决方案:

// 检查每个通道的数据
for (size_t i = 0; i < input_channels.size(); ++i) {
    if (input_channels[i].empty()) {
        throw std::runtime_error("Channel " + std::to_string(i) + " is empty");
    }
}

预防措施

1. 始终检查variant状态

if (data.channel_data.valueless_by_exception()) {
    throw std::runtime_error("Invalid variant state");
}

2. 验证容器大小

if (container.empty()) {
    throw std::runtime_error("Container is empty");
}

3. 边界检查

if (index >= container.size()) {
    throw std::runtime_error("Index out of bounds");
}

4. 类型安全访问

if (!std::holds_alternative<ExpectedType>(data.channel_data)) {
    throw std::runtime_error("Unexpected data type");
}

运行建议

  1. 先运行模式1: 确保解析器工作正常
  2. 观察调试输出: 检查每个阶段的数据状态
  3. 逐步排查: 如果出错,查看具体是哪个数据对象或通道
  4. 检查文件: 确认数据文件完整且格式正确

如果仍然出现段错误,请提供:

  • 完整的错误信息
  • 调试输出内容
  • 数据文件的基本信息(大小、格式等)