Reworks为嵌入式实时操作系统,arm架构

编译报错

1.报错:编译库缺失
分析:__atomic_load_8,属于原子操作库libatomic
正则表达式库 libregex相关函数 : __atomic_store_8 中的 "8" 代表8 字节,也就是64 位操作。意味着在编译器确定 self->r_value 的类型时,它被判定为 64 位类型(例如 long longdouble),因此需要 64 位的原子操作。
解决:换成64位qemu

2.从内存读出来的数据是u32类型,但是prom_counter_add()传入的r_value是double型,更改强制类型转化

运行报错(在64位QEMU中跑elf镜像)

1.调用初始化函数foo_metric_init报错:系统异常以及堆栈回溯,访问了无效内存

image.png
问题定位: r = pthread_rwlock_init(self->lock, NULL);初始化失败返回非零值,导致进入destyoy函数

分析:根据堆栈信息,最顶的函数通常为异常函数,向下依次是它的上层调用关系。所以最可能的异常发生在 prom_linked_list_purge 函数,极有可能是这个函数在执行过程中访问了无效的内存,进而引发了数据中止异常
从寄存器值看,X0通用寄存器可能访问了无效地址(例如 NULL 指针)

原因:多次销毁或释放内存

解决:要单独在资源配置里勾选【读写锁模块】

调试过程:在prom_map.c中把maxsize改成2,方便调试,原来是32 #define PROM_MAP_INITIAL_SIZE 2

2.输出的键值对和正确的对不上
image.png

分析:怀疑是执行完返回的时候报错

image.png

image.png

调完是正确的

注:如果要打印 size_t 类型的整数值,应该使用 %zu 格式符来打印 size_t 类型的数据。

3.跑完之后报错:
image.png

分析:问题出在prom_gauge_set()函数上,应该是在运行这个函数的过程中的异常和崩溃日志。报错信息这么长的原因:程序陷入了异常处理的循环,重复调用异常处理函数default_exception_handlerreworks_exception_handler,在异常处理函数中又出发了异常,没有一个异常被解决,所以栈帧越来越长。

thread_handler 在处理线程时调用了其他函数,可能是从 UserInitupdate 再到 prom_gauge_set 的链条。在某个函数调用中,栈帧可能被覆盖,导致返回地址被修改为无效的值(例如 0x415A2E1000000000)。

update() 结束,函数返回时,程序尝试跳转到这个无效地址,导致 Data Abort。由于 prom_gauge_set() 在图中标注了异常的地址 0x802665bc

在arm体系结构中,当程序执行BL指令进行函数调用时,LR保存返回地址,函数执行完成后会使用RET指令从LR中读取返回地址进行跳转。
Exception Program Counter(PC)程序计数器:发生异常时执行指令的地址(可以定位异常)
exception stack pointer(SP):发生异常时的栈指针
DFSR:状态码,在 ARM 架构中,不同的 DFSR 值代表不同的异常原因。
DFAR:程序试图访问该地址的内存,但是发生了异常。

PC是发生异常时的指令位置,DFAR是发生异常时的内存位置。

stack frame:函数调用栈
FP (Frame Pointer): 栈帧指针,指向当前栈帧的基地址。
LR (Link Register): 通常存储函数返回地址。
CPSR: 当前程序状态寄存器,保存状态标志和当前的 CPU 模式。
Instruction Abort 取指异常,处理器试图获取一条指令(即尝试读取并执行一条指令)时发生的异常
Data Abort 数据访问异常,处理器尝试访问数据(读或写操作)时发生的异常。

异常信息解读:
(1)第一次异常
Exception Program Counter:0x415A2E1000000000,程序试图执行位于 0x415A2E1000000000 处的指令,但该地址是无效的。所以不会执行指令也不会访问内存,导致instruction abort异常。
DFAR is 0x415A2E1000000000 程序在这个地址处尝试执行一条指令,并且这条指令试图访问同一个地址

(2)第二次异常
发生instruction abort异常后,程序自动进入异常处理流程,在处理过程中,又一次异常data abort,因为访问了无效内存 0x755F6C656E726573,此时异常指令的位置是有效的为0x802079B0

(3)后续异常
依旧是在异常处理过程中的异常,所以和第二次一样,进入了循环。
异常原因分析:PC被修改为0x415A2E1000000000,栈上的返回地址被错误地覆盖成了 0x415A2E1000000000。当程序从当前函数返回时,会试图跳转到这个错误的地址执行。

解决:

mapMi_t *mapMemInfo = (mapMi_t *)malloc(4 * sizeof(mapMi_t));
parseMemInfo(&mem, mapMemInfo);
//mapMemInfo没有分配内存!导致覆盖了栈上的返回地址,报错

3.buf输出是空的
原因:初始化创建收集器时,先添加了收集器里的指标,结果在注册收集器到注册表里时又重新创建了一个新的收集器,导致注册进去的收集器里没有任何指标,是空的。

移植成功后的效果展示:
image.png
image.png
image.png
image.png
image.png


f702
1 声望1 粉丝