__int128类型movaps指令crash

结论

在使用__int128时,如果__int128类型的内存起始地址不是按16字节对齐的话,有些汇编指令会抛出SIGSEGV使程序crash。

malloc在64位系统中申请的内存地址,是按16字节对齐的,但一般使用时经常会申请一块内存自己切割使用,往往会忽略一些类型的对齐。

案例

目前知道的两个指令是msse指令集的movaps和vmovaps,都是用来给int128赋值的,例如下面两种场景:

  1. (访问rax+0x30地址即 0x328dba8 + 0x30 = 0x328dbd8,对齐8字节,但没对齐16字节)
  2. (访问rax+0x30地址即 0x2d20b48 + 0x20 = 0x2d20b68,对齐8字节,但没对齐16字节)

复现

#include <stdio.h>

// gcc -g -O2 -Wall -msse4.2 -o test test.c

// core
typedef unsigned __int128 uint128;

// no core
// typedef unsigned __int128 uint128 __attribute__((aligned(8)));

static char mem[100];

typedef struct MySt
{
	int a;
	uint128 i;
	int b;
} MySt;

int main(void)
{
	MySt *st = (MySt *)(mem + 1);
	printf("st = %p\n", st);
	printf("st->i = %p\n", &st->i);
	__int128 tmp = 123123;
	st->a = 0;
	st->i = tmp * 123;
	st->b = 0;
	st = st;
	return st->i + 1 == 123;
}

gcc -g -O2 -Wall -msse4.2 -o test test.c可复现(不同的机器、编译器版本有不同的效果,可以看下编出来的二进制有无movaps指令,如果都是mov肯定没问题)。

相关推荐
云中双月7 天前
如何使用Ida Pro和Core Dump文件定位崩溃位置(Linux下无调试符号的进程专享)
linux·嵌入式·gdb·调试·gcc·崩溃·ida pro·ulimit·core dump·cross compile
witton13 天前
C语言实现Go的defer功能
c语言·clang·gcc·defer·attribute·cleanup·block type
码匠许师傅15 天前
【开源鸿蒙】OpenHarmony 5.0轻量系统最小开发环境搭建
python·pip·risc-v·openharmony·gcc·1024程序员节·hi3861
程序猿(攻城狮)17 天前
CentOS 7 安装gcc编译环境
linux·centos·gcc
CodingCos24 天前
【ARM 嵌入式 编译系列 2.9 -- GCC 编译如何避免赋值判断 if ( x = 0)】
arm开发·gcc·arm gcc·gcc 编译
shylyly_1 个月前
编译链接的过程发生了什么?
linux·gcc·底层·编译链接
时差freebright1 个月前
【Linux 报错】“make: ‘xxxx‘ is up to date.” 解决办法
linux·开发语言·gcc
时光飞逝的日子1 个月前
GNU链接器(LD):什么是符号?符号定义及实例解析
符号·gcc·链接脚本·gnu链接器·符号定义
DogDaoDao2 个月前
Windows 环境下 vscode 配置 C/C++ 环境
c语言·c++·windows·vscode·gcc·mingw-w64
Mr.zwX2 个月前
【CMake编译报错小复盘】CMAKE_CUDA_ARCHITECTURES,CMake version,GCC version问题
c++·编译·cmake·gcc