MIPS定位非法指令的bug
就项目适配中遇到的非法指令问题复现以及总结
在龙芯平台的MIPS架构中遇到SIGILL的报错:报错如下:

遇到这个问题很懵,有经验的会调试这个core的汇编语言找修复思路,拿着已经被修复的bug给自己涨涨经验和见识。
问题原因:
问题发生在将一个double型指针,赋值给void型指针,主要原因是龙芯平台MIPS架构需要强制字节对齐,要是没有对齐可能会引发总线错误或者非法指令的问题
解决方法:
因为项目中根据预编译参数可以使用不同的赋值方式,定义了强制对齐就走memcpy进行赋值,问题就得到解决。
脱离项目进行问题复现:(可惜的是到目前为止,并没有复现这个问题,但是我还是要记录下来,这个代码应该就是使用了未字节对齐的地址,但是没有出现SIGILL错误,我想是不是gcc编译过程中处理了什么东西,我要找到未能复现的原因)
头文件源码:
#ifndef _GDM_INCLUDE_LINUX_H
#define _GDM_INCLUDE_LINUX_H
#include<stdlib.h>
#include<stdio.h>
#define INLINE static inline
INLINE
void edn_write_double(void* dest,double v)
{
*(double*)dest = v;
}
double popen_get_double(const char* cmd)
{
double ans = 0;
char buf[256] = {0};
FILE* file;
unsigned int ret;
file = popen(cmd, "r");
ret = fread(buf, sizeof(char), sizeof(buf), file);
if (ret != 0)
{
ans = atof(buf);
}
pclose(file);
return ans;
}
#endif
.c文件:
#include "gdm_include_linux.h"
int main(void)
{
unsigned int i = 0x12345678;
double v;
v = popen_get_double("iostat - k 1 1 | grep -A100 \"^Device\" | awk '{sum+=$3} END {print sum}'"); //获取系统的磁盘下载速率
unsigned int* offset = &i;
unsigned char *p = (unsigned char *)&i;
*p = 0x00;
unsigned char* msg = malloc(20);
for(i=0;i<12;i++)
{
offset = &i;//模拟访问未对齐的内存地址
edn_write_double(msg+*offset,v);
printf("msg = %f",*msg);
}
free(msg);
return 0;
}
之后我就拿着这个代码进行复现,找到最实质的原因。
总结,可以参考现有的MIPS未字节对齐引发的错误博客
https://blog.csdn.net/comcat/article/details/1719217?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-1719217-blog-17203285.pc_relevant_3mothn_strategy_and_data_recovery&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-1719217-blog-17203285.pc_relevant_3mothn_strategy_and_data_recovery&utm_relevant_index=1
https://www.cnblogs.com/nx520zj/p/5653461.html
在代码的编写中要考虑到不同平台之间指令集的兼容性、还有大小端问题,要做到未雨绸缪,提高代码的可移植性和兼容性

浙公网安备 33010602011771号