Blaze277 2023-11-20 19:30 采纳率: 50%
浏览 22
已结题

Golang服务偶现段错误导致服务崩溃

1、遇到的问题
Golang编写的服务,向外提供HTTP,GRPC,WebSocket服务,本次新增CGO编写的基于libopus编解码的模块代码用于对外层传过来的opus音频进行解码,功能可以正常运行,但是在服务运行过程中,偶现
unexpected fault address 0x0
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x80 addr=0x0 pc=0x41776a]
错误导致服务崩溃。通常服务正常运行几个小时后报错,有时刚启动没多久就报错。
错误信息如下,每次堆栈错误信息都不相同

img


2、部分代码
cgo部分解码函数

int opusec_decode_stream(unsigned char* input,int inputSize,unsigned char* output,void *decoder,int sampleRate,int channels,int frameSizeMs,int bitrate){
    //输出缓冲区
    unsigned char oneframe_pcm_data[MAX_PACKET_SIZE * 2] = { 0 };
    //输入缓冲区
    int offset = 0;
    int outputLength = 0;
    opus_int16 oneframe_pcm_data_int16[MAX_PACKET_SIZE];
    memset(oneframe_pcm_data_int16, 0, MAX_PACKET_SIZE);
    unsigned char* inputEnd = input + inputSize;
    while(offset < inputSize){
        unsigned char ch[2];
        memcpy(ch,input + offset,2);
        opus_int32 len =  char_to_int(ch);
        offset+=2;
        if(inputEnd - input - offset < len){
            return outputLength;
        }
        //解码
        int nbSamples = opus_decode(decoder, input+offset, len, oneframe_pcm_data_int16, MAX_FRAME_SIZE, 0);
        offset+=len;
        if (nbSamples < 0)
        {
            break;
        }
        int i;
        //类型转换
        for (i = 0; i< channels * nbSamples && i < sizeof(oneframe_pcm_data) / sizeof(opus_int16); i++)
        {
            oneframe_pcm_data[2 * i] = oneframe_pcm_data_int16[i] & 0xFF;            //取低8位
            oneframe_pcm_data[2 * i + 1] = (oneframe_pcm_data_int16[i] >> 8) & 0xFF; //取高8位
        }
        memcpy(output+outputLength,oneframe_pcm_data,nbSamples * channels * sizeof(opus_int16));
        outputLength += nbSamples*channels * sizeof(opus_int16);
    }
    return outputLength;
}


3、初步解答思路
一开始以为是代码亦或者是环境问题,针对代码问题,在代码中补全了内存安全检查仍然存在上述问题;更换了机器也依然无法解决。
4、环境
Linux Go1.8 libopus

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 11月28日
    • 创建了问题 11月20日