c - 4 字节未对齐写入地址

标签 c memory

我正在将 CHibiOS RTOS 移植到 lm32 微处理器。

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

代码如下:

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);
}

最佳答案

wsp 的类型是什么?我建议不需要适当对齐字符数组或您将其定义的任何其他内容来存储 int32_t 类型。考虑总线如何按照惯例对齐以检索以 32 位为一组对齐的 int32_t 值。现在考虑“总线错误”在架构级别上的实际含义:

  1. 需要多次提取才能检索值(在性能方面不理想),或者
  2. 您的程序出现故障(甚至更糟)

在常见的 Intel 实现中,它使用第一个选项,除非您或您的调试器向您的程序注入(inject)一些疯狂的汇编(例如,参见 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 对象。

我认为您对指针运算感到困惑。你在读哪本书?

关于c - 4 字节未对齐写入地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15938525/

相关文章:

node.js - RSS 和堆有什么区别?

java - Java 应用程序运行时出现“无法分配内存”(errno=12) 错误

c - 打开文件 O_NONBLOCKING 在内核模块中丢失

c - 在循环迭代之间等待线程池中的线程

c++ - C题: no warning?

memory - 了解 Rust 中的 Rc 内存泄漏

c++ - C 和 C++ 中的多字 rune 字

c - C语言中将制表符分隔行解析为数组

java - 获取 "Java Heap Space"和 "Out of Memory"时的 Eclipse 内存设置

iOS - 内存和保留/释放问题