我正在执行一系列活动,以确保Redis在一组嵌入式系统中良好运行,包括树莓派。为了修复Redis中执行不对齐内存访问的某些代码路径(由于Redis 3.2引入的更改),我正在尝试强制PI在发生这种情况时记录有关不对齐内存访问的消息或向进程发送信号。通过这种方式,我可以确保Redis在不对齐访问是违规的地方能够良好运行,并且在相反的情况下,在可以执行但速度较慢的平台上运行得更快。 ARM v6(用于PI v1)显然能够处理不对齐的内存访问,因此如果我使用以下命令配置Linux以便向执行不对齐访问的进程发送信号:
echo 4 > /proc/cpu/alignment
然后运行以下程序:
#include <stdio.h>
#include <stdint.h>
int main(int argc, char **argv) {
char *buf = "foobareklsjdfklsjdfslkjfskdljfskdfjdslkjfdslkjfsd";
uint32_t *l = (uint32_t*) (buf+1);
printf("%p\n", l);
printf("%d\n", (int)*l);
return 0;
}
我看不到进程接收到任何信号,或者在/proc/cpu/alignment
计数器中递增。
我猜测这可能是由于ARM v6能够自动处理不对齐的地址,如果给定的CPU配置标志已设置。我的问题是,我的假设是否正确?如果是,如何强制PI版本1在发生不对齐访问时实际引发异常,以便Linux内核可以捕获它并发送信号、记录访问等,根据/proc/cpu/alignment设置?
编辑:值得注意的是,并非所有指令都能执行不对齐访问,即使在ARM v6中也是如此。例如STMDB、STMFD、LDMDB、LDMEA等多个字的指令确实会引发异常,并被Linux内核捕获。
pushf; orl $0x40000,(%rsp); popf
用于在 x86 上启用对齐检查,pushf; andl $0xFFFBFFFF,(%rsp); popf
用于禁用它。显然,操作系统必须配合,因为pushf/popf
是可怕的不干净特权分离破坏。 - EOF