ARM非对齐操作异常解决过程

在测试MF固件时,发生一个非常诡异的异常,代码如下:

    CLR_DBG_Commands::Monitor_EraseMemory* cmd = (CLR_DBG_Commands::Monitor_EraseMemory*)msg->m_payload;

    debug_printf("EraseMemory addr=0x%08x len=%d\r\n", cmd->m_address, cmd->m_length);

指定第二行代码时,会跳到异常处理程序,发生了6号异常(用法异常Usage Fault)

我对ARM还是非常陌生,不知道怎么可能发生这个问题。
在今天之前,这行代码执行了无数次也未曾出错,最近也没有修改该函数或者相关函数的代码,昨天倒是大量修改了其它代码。

1,百度找资料
关键点是用法异常Usage Fault,以此为关键字搜索。有资料(http://www.docin.com/p-633872264.html)指出,用法异常包括:执行未定义指令、非对齐操作、除零。
前后两个显然不可能,中间这个非对齐操作倒是引起了我的注意。因为阅读MFPK代码的时候看到很多对齐操作的设计。

2,Keil调试
在Keil中调试这两行代码

0x080071DA 6A74      LDR      r4,[r6,#0x24]
  1350:         debug_printf("EraseMemory addr=0x%08x len=%d\r\n", cmd->m_address, cmd->m_length);
  1351:
0x080071DC A012      ADR      r0,{pc}+4  ; @0x08007228
0x080071DE E9D41200  LDRD     r1,r2,[r4,#0]
0x080071E2 F001FD93  BL.W     debug_printf (0x08008D0C)

抛出异常的是0x080071DE这一行,代码是LDRD r1,r2,[r4,#0],大意是把r4开始,偏移#0的数据加载到r1,下一个字加载到r2
从寄存其中看到,r4此时是0x200006D2,这是半字对齐而不是字对齐。
奇怪了,MDK为啥编译一个半字对齐的呢?
回到第一行代码的msg->m_payload,它是关键。因为它就是0x200006D2,如果r4没有字对齐,那么肯定跟这个msg->m_payload有关。
我们看看msg->m_payload是哪里分配的!

3,寻根
从代码中看到msg->m_payload来自msg->m_payload = pThis->m_receptionBuffer;
而m_receptionBuffer的声明

    COM_HANDLE    m_port;
    UINT8         m_receptionBuffer[ 2048 ];
    UINT32        m_flags;
    UINT32        m_lastPacketSequence;
    WP_Controller m_controller;

到这里,就明白了!
因为我昨天把typedef INT32 COM_HANDLE;改为了typedef INT16 COM_HANDLE;

非对齐操作相关资料
http://www.docin.com/p-218037008.html

时间: 2024-10-10 12:56:52

ARM非对齐操作异常解决过程的相关文章

SVN操作异常解决日志

1 svn locked某个目录-无法进行更新 产生这种情况大多是因为上次svn命令执行失败且被锁定了.如果cleanup没有效果的话只好手动删除锁定文件. 在命令提示符下cd 到svn项目出现问题的文件所在目录下,然后执行如下命令 del lock /q/s 就把锁删掉了.如图所示: 2.svn remains in conflict错误解决 情形:当有人在对某文件进行修改,假设为A文件,并提交至svn服务器,如果此时你正在修改A页面,并对其进行更新.会出现一些残余文件信息.如果在未删除这些文

ARM 非对齐的数据访问操作

I’m confused about unaligned memory accesses on ARM. My understanding was that they’re not allowed — that is, dereferencing a 32-bit value from a pointer that’s not four-byte aligned will crash. I’ve run into such crashes before. But right now I’ve g

[转]MIPS 下非对齐访问的问题

1.问题 MIPS 下使用访存指令读取或写入数据单元时,目标地址必须是所访问之数据单元字节数的整数倍,这个叫做地址对齐. 比如在 MIPS 平台上,lh 读取一个半字时,存储器的地址必须是 2 的整数倍: lw 读取一个字时,存储器的地址必须是 4的整数倍: sd 写入一个双字时,存储器的地址必须是 8 的整数倍.倘若访存时,目标地址不对齐,则会引起异常,典型的是系统提示“总线错误”后,直接杀死进程. 看一个测试程序(龙芯2E平台): #include <stdio.h>#include &l

关于一个需求引发的事务操作和锁-记录解决过程和思路

参考资料: http://openwares.net/java/spring_mybatis_transaction.htmlspring,mybatis事务管理配置与@Transactional注解使用 http://www.cnblogs.com/mingxuan/archive/2011/10/11/2207560.html锁行还是锁表的实践验证 http://blog.csdn.net/hushanfeng110/article/details/50174787使用mybatis 实现乐

(原)记一次CentOS7 磁盘空间大小异常的解决过程

环境:kvm系统:CentOS7故障描述:10g的ssd,可使用大小仅有2g解决过程: ? ? 某次重装系统后,安装软件总提示磁盘空间不足,检查之下发现仅有2G空间,实则明明是10G的ssd,以下为排错过程: 1.df -h查看vda1大小为2.7G #df -h Filesystem Size Used Avail Use% Mounted on /dev/vda1 2.7G 2.4G 236M 91% / devtmpfs 234M 0 234M 0% /dev tmpfs 244M 0 2

非对齐访问和Alignment Fault

什么是对齐异常? 简单来说,当CPU访问内存地址时,如果发现访问的地址是不对齐的,硬件(部分)就会自动触发对齐异常.对齐即要求被访问的地址满足其数据类型的位宽要求,比如要访问一个4字节int型的数据,但是提供的地址不是4字节对齐的,那就是不对齐了.也就是说要访问的数据的位宽长度是多少,那么访问的地址就必须是按这个位宽长度对齐的.如果是char类型的,那就没有没有对齐要求了. 为什么在部分硬件上出现? 部分CPU硬件支持非对齐访问,典型的就是X86,X86硬件会自动处理非对齐访问情况,对软件透明,

MySQL数据库ab主从复制出错及解决过程

MySQL数据库ab主从复制出错及解决过程 一.mysql主从服务器报错描述:Slave_IO_Running=NO,Slave_SQL_Running=YES,Last_Errno=0 mysql slave stop ; mysql slave start; mysql show slave status ; 如果Slave_IO_Running=YES ...解决过程 :1 如果:Slave_IO_Running=NO,Slave_SQL_Running=YES,Last_Errno=0m

检查型异常和非检查型异常

对于因为编程错误而导致的异常,或者是不能期望程序捕获的异常(解除引用一个空指针,数组越界,除零,等等),为了使开发人员免于处理这些异常,一些异常被命名为非检查型异常(即那些继承自 RuntimeException 的异常)并且不需要进行声明. Checked Exception和Unchecked Exception的几点不同之处 方法签名是否需要声明exception 调用该方法时是否需要捕获exception exception产生的时候JVM控制程序的状态 Sun 的"The JavaTu

[转]线上GC故障解决过程记录

排查了三四个小时,终于解决了这个GC问题,记录解决过程于此,希望对大家有所帮助.本文假定读者已具备基本的GC常识和JVM调优知识,关于JVM调优工具使用可以查看我在同一分类下的另一篇文章: http://my.oschina.net/feichexia/blog/196575 背景说明 发生问题的系统部署在Unix上,发生问题前已经跑了两周多了. 其中我用到了Hadoop源码中的CountingBloomFilter,并将其修改成了线程安全的实现(详情见:AdjustedCountingBloo