---
title: 对结构体中的变量进行原子操作时程序异常coredump
description: "程序调用原子操作函数对结构体中的变量进行原子操作，程序coredump，堆栈如下："
url: https://www.hikunpeng.com/document/detail/zh/kunpenggrf/codeprtr/kunpengtaishanporting_12_0014.html
sourcePath: /source/zh/kunpenggrf/codeprtr/kunpengtaishanporting_12_0014.html
indexId: 0ad25d50d2010a73ee850cd2ea6b2d7e8c539abcb3a0d95f62e4b6fe047b571865
---
# 对结构体中的变量进行原子操作时程序异常coredump

#### 现象描述

程序调用原子操作函数对结构体中的变量进行原子操作，程序coredump，堆栈如下：

```
Program received signal SIGBUS, Bus error.
0x000000000040083c in main () at /root/test/src/main.c:19
19          __sync_add_and_fetch(&a.count, step);
(gdb) disassemble
Dump of assembler code for function main:
0x0000000000400824 <+0>:     sub     sp, sp, #0x10
0x0000000000400828 <+4>:     mov     x0, #0x1                        // #1
0x000000000040082c <+8>:     str     x0, [sp, #8]
0x0000000000400830 <+12>:    adrp    x0, 0x420000 <__libc_start_main@got.plt>
0x0000000000400834 <+16>:    add     x0, x0, #0x31 // 将变量的地址放入到x0寄存器
0x0000000000400838 <+20>:    ldr     x1, [sp, #8] //
指定ldxr
取数据的长度（此处为8
字节）
=> 0x000000000040083c <+24>:    ldxr    x2, [x0] // ldxr
从x0
寄存器指向的内存地址中取值
0x0000000000400840 <+28>:    add     x2, x2, x1
0x0000000000400844 <+32>:    stlxr   w3, x2, [x0]
0x0000000000400848 <+36>:    cbnz    w3, 0x40083c <main+24>
0x000000000040084c <+40>:    dmb     ish
0x0000000000400850 <+44>:    mov     w0, #0x0                        // #0
0x0000000000400854 <+48>:    add     sp, sp, #0x10
0x0000000000400858 <+52>:    ret
End of assembler dump.
(gdb) p /x $x0
$4 = 0x420039 // x0
寄存器存放的变量地址不在8
字节地址对齐处
```


#### 问题原因

ARM64平台对变量的原子操作、锁操作等用到了ldaxr、stlxr等指令，这些指令要求变量地址必须按变量长度对齐，否则执行指令会触发异常，导致程序coredump。

一般是因为代码中对结构体进行强制字节对齐，导致变量地址不在对齐位置上，对这些变量进行原子操作、锁操作等会触发问题。


#### 处理步骤

1. 在代码中搜索“#pragma pack”关键字（该指令改变了编译器默认的对齐方式）。
2. 找到使用了字节对齐的结构体，修改代码。
  如果结构体中变量会被作为原子操作、自旋锁、互斥锁、信号量、读写锁的输入参数，则需要修改代码保证这些变量按变量长度对齐。
