4字节未对齐写入地址

时间:2013-04-10 23:52:14

标签: c memory

我正在为lm32微处理器做一个CHibiOS RTOS的端口。

我在第一行代码中存在未对齐内存地址的问题,我编写了这个代码来设置新线程。 当他们试图写入内存时,其他三行已经给我一个类似的问题,但我解决了它对齐intctxcontext结构__attribute__((packed));

代码如下:

tp->p_ctx.sp = (struct intctx*)((uint32_t *)wsp + size - sizeof(struct intctx));
tp->p_ctx.sp->r1 = (uint32_t)arg;
tp->p_ctx.sp->r2 = (uint32_t)pf;
tp->p_ctx.sp->ra = (uint32_t)port_thread_start;

结构体在我实现的头文件中定义:

struct intctx {
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t r9;
uint32_t r10;
uint32_t r11;
uint32_t r12;
uint32_t r13;
uint32_t r14;
uint32_t r15;
uint32_t r16;
uint32_t r17;
uint32_t r18;
uint32_t r19;
uint32_t r20;
uint32_t r21;
uint32_t r22;
uint32_t r23;
uint32_t r24;
uint32_t r25;
uint32_t gp;
uint32_t fp;
uint32_t sp;
uint32_t ra;
uint32_t ea;
uint32_t ba;
} __attribute__((packed));

struct context {
struct intctx *sp;
} __attribute__((packed));

我使用gdb进行调试,当它尝试执行该行时:

tp->p_ctx.sp = (struct intctx*)((uint32_t *)wsp + size - sizeof(struct intctx)); 

它给出了以下问题:

core: 4 byte misaligned write to address 0x107409 at 0x100b20

Program received signal SIGBUS, Bus error.
0x00000080 in ?? ()

任何人都可以帮助我吗?谢谢。


wsp通过引用传递为函数的参数,其中这些代码行是。 wsp的类型为void *: 但这是一个Thread *类型,wsp指向空闲的线程结构。

代码行在ChibiOS支持的其他架构中的相同功能中实现,我只做了同样的事情:

tp->p_ctx.sp =  (struct intctx*)((uint32_t *)wsp + size - sizeof(struct intctx));

这是完整的功能:

Thread *chThdCreateI(void *wsp, size_t size,
                 tprio_t prio, tfunc_t pf, void *arg) {
/* Thread structure is laid out in the lower part of the thread workspace.*/
Thread *tp = wsp;

chDbgCheckClassI();

chDbgCheck((wsp != NULL) && (size >= THD_WA_SIZE(0)) &&
         (prio <= HIGHPRIO) && (pf != NULL),
         "chThdCreateI");
tp->p_ctx.sp =  (struct intctx*)((uint32_t *)wsp + size - sizeof(struct intctx));
tp->p_ctx.sp->r1 = (uint32_t)arg;
tp->p_ctx.sp->r2 = (uint32_t)pf;
tp->p_ctx.sp->ra = (uint32_t)port_thread_start;
//SETUP_CONTEXT(wsp, size, pf, arg);
return _thread_init(tp, prio);
}

1 个答案:

答案 0 :(得分:1)

wsp的类型是什么?我建议使用一系列字符或其他任何你定义的字符,不需要与存储int32_t类型进行适当的对齐。考虑如何按常规对齐总线以检索以32位组对齐的int32_t值。现在考虑一下“总线错误”在架构级别上可能意味着什么:

  1. 需要多次提取才能检索该值(在性能方面不合需要)或
  2. 您的程序出现故障(甚至更糟)
  3. 在常见的英特尔实现中,它使用第一个选项,除非您或您的调试器为程序注入一些程序集疯狂(例如,请参阅this wikipedia article)。在C中,它只是简单的未定义行为。确保wsp适当对齐以指向int32_t类型。你可以通过确保它指向其中一个来做到这一点:

    1. int32_t变量或
    2. 数组中的任何int32_t个对象,或:
    3. malloc,calloc或realloc的返回值,或:
    4. “malloc / calloc / realloc返回值的任何int32_t个对象都被视为指向int32_t的指针。”
    5. 我认为你对指针运算感到困惑。你正在读哪本书?