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

Ubuntu Server下读取机器码二进制文件触发Segmentation Fault问题排查

程序Segmentation Fault问题排查与修复

在Linux Ubuntu Server环境下编写程序,目标是读取机器码二进制文件并解析输出汇编代码。程序运行至hexdump函数中cout << "inst " << (i+j) / 4 << ": ";语句后,出现**Segmentation Fault(core dumped)**错误导致执行终止,此前buflen(值为24)可正常打印。以下是原始代码(find、work函数暂未实现或未使用):

#include <fstream>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

string find(char op[7]);
void work(string inst, short* ins);

void hexdump(void* ptr, const int buflen)
{
unsigned char* buf = (unsigned char*)ptr;
int i, j, d, hex = 0;
short* ins;
string op;
for (i = 0; i < buflen; i += 16) {
    for (j = 0; j < 16; j += 4) { 
        if (i + j < buflen) {
            cout << buflen << endl;
            cout << "inst " << (i+j) / 4 << ": ";
            for (int a = 0; a < 32; a += 8) {
                d = buf[i + j + a / 8];

                for (int k = 0; k < 8; k++) {
                    if (d % 2 != 0) {
                        ins[k + a] = 1;
                    }
                    else {
                        ins[k + a] = 0;
                    }
                    
                    d = d / 2;
                }
            }
            for (int i = 31; i >= 0; i -= 4) {
                hex = hex + ins[i] * 8;
                hex = hex + ins[i - 1] * 4;
                hex = hex + ins[i - 2] * 2;
                hex = hex + ins[i - 3] * 1;
                if (hex == 10)
                    printf("a");
                else if (hex == 11)
                    printf("b");
                else if (hex == 12)
                    printf("c");
                else if (hex == 13)
                    printf("d");
                else if (hex == 14)
                    printf("e");
                else if (hex == 15)
                    printf("f");
                else
                    printf("%d", hex);
                hex = 0;
            }
            for (int i = 6; i >=0; i--) {
                if (ins[i] == 1)
                    op.append("1");
                else if (ins[i] == 0)
                    op.append("0");
            }
            cout << endl << op << endl;
            //work(find(op), ins);
            printf("\n");
        }
    }
}
}

int main(int argc, char* argv[])
{
ifstream in;

in.open(argv[1], ios::in | ios::binary);
if (in.is_open())
{
    // get the starting position
    streampos start = in.tellg();

    // go to the end
    in.seekg(0, std::ios::end);

    // get the ending position
    streampos end = in.tellg();

    // go back to the start
    in.seekg(0, std::ios::beg);

    // create a vector to hold the data that
    // is resized to the total size of the file    
    std::vector<char> contents;
    contents.resize(static_cast<size_t>(end - start));

    // read it in
    in.read(&contents[0], contents.size());

    // print it out (for clarity)
    hexdump(contents.data(), contents.size());
}
in.close();
return 0;
}
string find(char op[7]) {
   string inst("unknown instruction");
   if(op=="")
   return inst;
}
void work(string inst, short* ins);

错误原因分析

  • 未初始化指针ins:hexdump函数中仅声明short* ins;但未分配内存,直接对ins[k + a]赋值会访问非法内存,这是段错误的核心原因。
  • 变量名冲突:内层循环使用int i作为变量名,覆盖了外层循环的i,导致循环逻辑混乱。
  • op字符串未清空:每次循环后op会累积内容,导致后续输出错误。
  • find函数参数类型不匹配:声明的find(char op[7])与调用时传入的string op类型不兼容。
  • find函数缺少默认返回值:未满足所有分支的返回要求,存在未定义行为。

修复后的代码

#include <fstream>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

string find(string op);
void work(string inst, short* ins);

void hexdump(void* ptr, const int buflen)
{
    unsigned char* buf = (unsigned char*)ptr;
    int i, j, d, hex = 0;
    short ins[32];  // 直接分配固定大小数组,替代未初始化指针
    string op;
    for (i = 0; i < buflen; i += 16) {
        for (j = 0; j < 16; j += 4) { 
            if (i + j < buflen) {
                op.clear();  // 每次循环清空字符串
                cout << buflen << endl;
                cout << "inst " << (i+j) / 4 << ": ";
                for (int a = 0; a < 32; a += 8) {
                    d = buf[i + j + a / 8];

                    for (int k = 0; k < 8; k++) {
                        ins[k + a] = (d % 2 != 0) ? 1 : 0;
                        d /= 2;
                    }
                }
                // 修改内层循环变量名,避免覆盖外层i
                for (int idx = 31; idx >= 0; idx -= 4) {
                    hex = ins[idx] * 8 + ins[idx - 1] * 4 + ins[idx - 2] * 2 + ins[idx - 3] * 1;
                    if (hex >= 10 && hex <= 15)
                        printf("%c", 'a' + hex - 10);
                    else
                        printf("%d", hex);
                    hex = 0;
                }
                // 修改内层循环变量名,避免覆盖外层i
                for (int idx = 6; idx >= 0; idx--) {
                    op += (ins[idx] == 1) ? "1" : "0";
                }
                cout << endl << op << endl;
                // work(find(op), ins);
                printf("\n");
            }
        }
    }
}

int main(int argc, char* argv[])
{
    ifstream in;

    in.open(argv[1], ios::in | ios::binary);
    if (in.is_open())
    {
        streampos start = in.tellg();
        in.seekg(0, std::ios::end);
        streampos end = in.tellg();
        in.seekg(0, std::ios::beg);

        std::vector<char> contents;
        contents.resize(static_cast<size_t>(end - start));
        in.read(&contents[0], contents.size());

        hexdump(contents.data(), contents.size());
    }
    in.close();
    return 0;
}

string find(string op) {
    string inst("unknown instruction");
    if(op.empty())
        return inst;
    return inst;  // 补充默认返回值
}

void work(string inst, short* ins) {
    // 后续实现指令解析逻辑
}

主要修改点

  1. 将short* ins;改为short ins[32];,在栈上分配固定大小数组,避免非法内存访问。
  2. 修改内层循环变量名为idx,避免覆盖外层循环的i变量。
  3. 每次处理指令前调用op.clear(),清空字符串防止内容累积。
  4. 修正find函数参数类型为string,使用op.empty()判断空字符串,并补充默认返回值。
  5. 简化十六进制输出逻辑,用'a' + hex -10直接转换字母,代码更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 06:45:36