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]
错误导致服务崩溃。通常服务正常运行几个小时后报错,有时刚启动没多久就报错。
错误信息如下,每次堆栈错误信息都不相同

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