当前位置: 首页 > news >正文

为什么同样的C代码在arm64-v8a可以跑,在armeabi-v7a会奔溃?

文章目录

  • 背景
    • 过程
      • 第一个坑
      • 第二个坑
  • arm64-v8a 和 armeabi-v7a的区别
  • 实例
    • 64位,Android设备CPU:arm64-v8a
    • 32位,Android设备CPU:armeabi-v7a
  • 基本数据类型在32位和64位的区别
    • 指针长度在32位和64位的区别
  • 其他可能性
  • chatgpt回答参考

背景

使用NDK开发项目的一个安全库的时候,踩了一个坑。在这里做一个记录和总结,避免以后重复踩坑。
需求:开发安全库,用作密钥加密解密,体系位非对称密钥体系。
经历:使用的是合作公司提供的C源码,通过JNI接入C代码,提供给Java层调用。

过程

第一个坑

运行的时候Android stduio显示列链接错误,怀疑是CMake的问题。新建一个test.c和test.h可以正常运行。发现是C源码里面没有加上:

#ifdef __cplusplus
extern "C"
{
#endif
//c代码声明
#ifdef __cplusplus
};
#endif

导致C++链接时候和C的符号对不上,链接失败,坑的地方在于编译器没有提示这个问题。只能这样试出来。

第二个坑

前面几个接口可以正常运行,中间某个接口不能打印,程序不崩溃,只是不能打印。
同样的代码在Linux设备可以正常运行。
debug进去C源码里面进行代码review和数据观察分析,发现里面定义了long 、long long之类的变量。每次在某些循环操作里面断开debug。没能找出原因。
在代码里面加上数据打印,在怀疑的代码段加上大量的打印日志,观察数据是否越界。数据太多,也发现也没有越界导致crash。
调试和思路了半天,没有思路了。那另外一台机器来跑一下,bingo!
居然可以正常打印结果值了。

首先第一件想到的是,可能是cpu架构不同导致的。
第一台机器是arm64-v8a,第二台测试正常的cpu是armeabi-v7a。
好吧,他们的区别是一台是64位,一台是32位。
怀疑就是不同位数cpu里面数据长度不同导致的。

arm64-v8a 和 armeabi-v7a的区别

在Android开发中,arm64-v8aarmeabi-v7a 是两种不同的CPU架构。arm64-v8a 适用于64位ARM处理器,而 armeabi-v7a 适用于32位ARM处理器。

先来跑一个实例看看。

实例

void print64And32(){//写一个代码32位机器上运行时,输出sizeof(指针)的结果是多少,64位机器上运行时,输出sizeof(指针)的结果是多少?LOGD("sizeof(int) = %d\n", sizeof(int));LOGD("sizeof(long) = %d\n", sizeof(long));LOGD("sizeof(long long) = %d\n", sizeof(long long));LOGD("sizeof(char) = %d\n", sizeof(char));LOGD("sizeof(float) = %d\n", sizeof(float));LOGD("sizeof(double) = %d\n", sizeof(double));LOGD("sizeof(void *) = %d\n", sizeof(void *));LOGD("sizeof(char *) = %d\n", sizeof(char *));LOGD("sizeof(int *) = %d\n", sizeof(int *));LOGD("sizeof(long *) = %d\n", sizeof(long *));LOGD("sizeof(long long *) = %d\n", sizeof(long long *));LOGD("sizeof(float *) = %d\n", sizeof(float *));LOGD("sizeof(double *) = %d\n", sizeof(double *));}

64位,Android设备CPU:arm64-v8a

sizeof(int) = 4
sizeof(long) = 8
sizeof(long long) = 8
sizeof(char) = 1
sizeof(float) = 4
sizeof(double) = 8
sizeof(void *) = 8
sizeof(char *) = 8
sizeof(int *) = 8
sizeof(long *) = 8
sizeof(long long *) = 8
sizeof(float *) = 8
sizeof(double *) = 8

32位,Android设备CPU:armeabi-v7a

sizeof(int) = 4
sizeof(long) = 4
sizeof(long long) = 8
sizeof(char) = 1
sizeof(float) = 4
sizeof(double) = 8
sizeof(void *) = 4
sizeof(char *) = 4
sizeof(int *) = 4
sizeof(long *) = 4
sizeof(long long *) = 4
sizeof(float *) = 4
sizeof(double *) = 4

基本数据类型在32位和64位的区别

从上述实测可以知道,在32位机器上,基本数据类型的大小如下:

  • int:4字节
  • long:4字节
  • long long:8字节
  • char:1字节
  • float:4字节
  • double:8字节

在64位机器上,基本数据类型的大小如下:

  • int:4字节
  • long:8字节
  • long long:8字节
  • char:1字节
  • float:4字节
  • double:8字节

需要注意的是,指针的大小在32位和64位机器上都是相同的,都是8字节。

指针长度在32位和64位的区别

32位机器上运行时,输出sizeof(指针)的结果是4。
64位机器上运行时,输出sizeof(指针)的结果是8。

其他可能性

  1. 架构相关的问题: 你的应用程序可能包含了特定于 arm64-v8a 架构的代码,而这段代码在 armeabi-v7a 上无法正确运行。确保你的应用程序中没有架构相关的问题,并且所有的本地代码都是通用的。

  2. 依赖库问题: 如果你的应用程序使用了本地库(例如C/C++库),这些库可能是特定于 arm64-v8a 的。确保你的应用程序包含适用于 armeabi-v7a 的版本的这些库。

  3. 指令集兼容性: arm64-v8a 使用ARMv8-A指令集,而 armeabi-v7a 使用ARMv7-A指令集。确保你的应用程序中的本地代码对目标指令集是兼容的。

  4. ABI Filters: 在你的 build.gradle 文件中,可能设置了 ABI Filters,导致只有 arm64-v8a 被打包到 APK 中。检查你的构建配置,确保包含了 armeabi-v7a 的支持。

chatgpt回答参考

当你的 C 代码在 32 位处理器上能够正常运行,但在 64 位处理器上出现问题时,可能有一些常见的原因:

  1. 指针大小和类型问题: 64 位处理器上的指针大小为 8 字节,而在 32 位处理器上为 4 字节。如果你的代码中存在对指针大小的假设或者类型转换问题,可能导致在 64 位系统上出现问题。请确保你的代码对指针操作和类型大小有正确的处理。

  2. 整数溢出: 如果你的代码依赖于特定的整数大小,可能会在 64 位系统上溢出。在 64 位系统上,int 类型仍然是 32 位,但 long 类型变为 64 位。确保你的代码中没有整数溢出的问题。

  3. 对齐问题: 在 64 位系统上,对齐要求可能更加严格。如果你的代码依赖于特定的数据结构对齐方式,确保你的结构体或变量的对齐方式是正确的。

  4. 未初始化变量: 64 位系统上的内存布局可能与 32 位系统不同。确保你的代码中所有的变量都被正确初始化,以防止使用未初始化的内存。

  5. 依赖的库或第三方代码: 如果你的代码依赖于特定的库或第三方代码,确保这些库在 64 位系统上是兼容的。有时,问题可能并不是在你的代码中,而是在你依赖的库中。

  6. 汇编语言代码: 如果你的代码包含了汇编语言部分,确保这些汇编语言代码是对 64 位系统的正确支持。

总体而言,要确保 C 代码能够在 64 位处理器上正确运行,需要注意 32 位和 64 位系统之间的差异,并确保代码中没有与平台相关的假设。最好的做法是使用编译器提供的宏来处理不同平台的区别,以确保代码的可移植性。

相关文章:

为什么同样的C代码在arm64-v8a可以跑,在armeabi-v7a会奔溃?

文章目录 背景过程第一个坑第二个坑 arm64-v8a 和 armeabi-v7a的区别实例64位,Android设备CPU:arm64-v8a32位,Android设备CPU:armeabi-v7a 基本数据类型在32位和64位的区别指针长度在32位和64位的区别 其他可能性chatgpt回答参考 背景 使用NDK开发项目的…...

C++初学者线路图 23年12月

高精度计算 1. 高精度加减法 高精度加减法课程(12月1日~12月4日)高精度加减法配套程序(12月5日~12月6日) 2. 高精度乘法 高精度乘法课程(12月7日~12月10日)高精度乘法…...

Day37| Leetcode 738. 单调递增的数字

今天就一个题目,做完吃完饭抓紧做六级试题。 Leetcode 738. 单调递增的数字 题目链接 738 单调递增的数字 本题目思路还是比较巧妙的,对于98,一旦出现strNum[i - 1] > strNum[i]的情况(非单调递增),首…...

【工具分享】| 阅读论文神器 使用技巧 AI润色 AI翻译

文章目录 1 使用技巧1.1 功能一 即时翻译1.2 功能二 文献跳转1.3 功能三 多设备阅读1.4 功能四 小组讨论笔记共享1.5 功能五 个人文献管理 2 其他功能 超级喜欢Readpaper这一款论文阅读软件,吹爆他哈哈 为什么? 当然是他可以解决我们传统阅读论文的种种…...

String.prototype.match进行==判断

今天发现一个String.prototype.match的奇葩用法 export const isWeChat (() > {let ua window.navigator.userAgent.toLowerCase();return ua.match(/MicroMessenger/i) "micromessenger"; })();这是我在网站上找到的一个判断是否是微信浏览器的方法&#xff…...

less 笔记

<link rel"stylesheet/less" type"text/css" href"styles.less" /> <script src"https://cdn.jsdelivr.net/npm/less4" ></script>变量&#xff08;Variables&#xff09; 原生已支持 --前缀定义属性 var() 函数获取…...

Java中的异常你了解多少?

目录 一.认识异常二.异常分类三.异常的分类1.编译时异常2.运行时异常 四.异常的处理1.LYBL&#xff1a;事前防御型2.EAFP&#xff1a;事后认错型 五.异常的抛出Throw注意事项 六.异常的捕获1.异常的捕获2.异常声明throws3.try-catch捕获并处理 七.自定义异常 一.认识异常 在Jav…...

查找算法及哈希表

1 二分查找 1.1 重要概念 拟解决的问题&#xff1a;判断某个区间是否包含某个元素&#xff0c;无法确定区间中包含重复元素的具体位置&#xff1b;使用条件&#xff1a;查找的区间必须符合单调性&#xff1b;本质&#xff1a;采用分治思想&#xff0c;将某个单调区间一分为二…...

ELK分布式日志管理平台部署

目录 一、ELK概述 1、ELK概念&#xff1a; 2、其他数据收集工具&#xff1a; 3、ELK工作流程图&#xff1a; 4、ELK 的工作原理&#xff1a; 5、日志系统的特征&#xff1a; 二、实验部署&#xff1a; 1、ELK Elasticsearch 集群部署 2、安装 Elasticsearch-head 插件 …...

四、虚拟机网络配置

目录 1、VMware网卡配置模式 1.1 桥接模式 1.2 NAT模式 1.3 仅主机模式 ​​​​​​​2、编辑虚拟机的网络编辑器 ​​​​​​​3、编辑Window的虚拟网卡 ​​​​​​​4、修改IP地址为静态 4.1 查看网卡名字 4.2 编辑修改网卡IP地址的配置文件 4.3 重启网络: 4.…...

四、Lua循环

文章目录 一、while(循环条件)二、for&#xff08;一&#xff09;数值for&#xff08;二&#xff09;泛型for&#xff08;三&#xff09;repeat util 既然同为编程语言&#xff0c;那么控制逻辑里的循环就不能缺少&#xff0c;它可以帮助我们实现有规律的重复操作&#xff0c;而…...

生成对抗网络(GAN)手写数字生成

文章目录 一、前言二、前期工作1. 设置GPU&#xff08;如果使用的是CPU可以忽略这步&#xff09; 二、什么是生成对抗网络1. 简单介绍2. 应用领域 三、网络结构四、构建生成器五、构建鉴别器六、训练模型1. 保存样例图片2. 训练模型 七、生成动图 一、前言 我的环境&#xff1…...

LeetCode Hot100 31.下一个排列

题目&#xff1a; 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如&#xff0c;arr [1,2,3] &#xff0c;以下这些都可以视作 arr 的排列&#xff1a;[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列…...

Redis主从与哨兵架构详解

目录 主从架构 主从环境搭建 主从复制流程 1. 全量复制 2. 部分复制 主从风暴 哨兵架构 概念 哨兵环境搭建 主从架构 主从环境搭建 1. 复制一份redis.conf文件, 修改下面几行配置 port 6380 pidfile /var/run/redis_6380.pid logfile "6380.log" dir /usr/…...

Linux:docker的数据管理(6)

数据管理操作*方便查看容器内产生的数据 *多容器间实现数据共享 两种管理方式数据卷 数据卷容器 1.数据卷 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中&#xff0c;可将宿主机的目录挂载到数据卷上&#xff0c;对数据卷的修改操作立刻可见&#xff0c;并且更新数…...

深入理解Zookeeper系列-1.初识Zoookeeper

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理&#x1f525;如果感觉博主的文章还不错的话&#xff…...

芯片技术探索:了解构芯片的设计与制造之旅

芯片技术探索:了解构芯片的设计与制造之旅 一、引言 随着现代科技的飞速发展,芯片作为信息技术的核心,已经渗透到我们生活的方方面面。从智能手机、电视、汽车到医疗设备和工业控制系统,芯片在各个领域都发挥着至关重要的作用。然而,对于大多数人来说,芯片仍然是一个神秘…...

STM32 超声波模块(HC-SR04)

HC-SR04介绍 典型工作电压&#xff1a;5v &#xff08;如果你的超声波模块没有工作&#xff0c;可以看一下是不是电压不够&#xff09;超小静态工作电流&#xff1a;<2mA 感应角度&#xff1a;<15 &#xff08;超声波模块&#xff0c;是一个范围式的探…...

ELK+Filebeat

Filebeat概述 1.Filebeat简介 Filebeat是一款轻量级的日志收集工具&#xff0c;可以在非JAVA环境下运行。 因此&#xff0c;Filebeat常被用在非JAVAf的服务器上用于替代Logstash&#xff0c;收集日志信息。实际上&#xff0c;Filebeat几乎可以起到与Logstash相同的作用&…...

MySql之锁表、锁行解决方案

查询正在使用的表&#xff0c;没有跑业务&#xff0c;一般情况下是锁表了 show open tables where in_use > 0 ;查看进程&#xff0c;可以看到Command类型&#xff08;Sleep为阻塞线程&#xff09; show processlist;kill事务&#xff0c;kill 进程Id kill 8193583;其他 …...

别再复制粘贴了!Element Plus 表格组件与SpringBoot后端数据联调实战

别再复制粘贴了&#xff01;Element Plus 表格组件与SpringBoot后端数据联调实战 在前后端分离的开发模式中&#xff0c;前端表格组件与后端数据的动态联调是每个开发者必须掌握的技能。Element Plus作为Vue3生态中最受欢迎的UI组件库之一&#xff0c;其表格组件(el-table)的灵…...

别再手动拼图了!用Godot4的TileMap快速搭建2D游戏场景(附图层与相机跟随技巧)

别再手动拼图了&#xff01;用Godot4的TileMap快速搭建2D游戏场景&#xff08;附图层与相机跟随技巧&#xff09; 在独立游戏开发中&#xff0c;场景搭建往往是耗时最长的环节之一。许多新手开发者习惯用Sprite节点逐个摆放场景元素&#xff0c;这不仅效率低下&#xff0c;后期…...

ContentBranch+CFBranch混合电影推荐模型|全网独家复现,深度学习实战篇 引入双分支融合架构,兼顾内容特征与协同信号、助力冷启动缓解、数据稀疏性优化、推荐精度有效涨点

目录 一、前言:混合推荐模型的核心价值与行业痛点 二、模型核心原理(全网独家拆解,通俗易懂) 2.1 整体架构逻辑 2.2 ContentBranch(内容分支)原理详解 2.3 CFBranch(协同过滤分支)原理详解 2.4 特征融合与预测层原理 2.5 模型优势总结 三、环境搭建(全平台适配…...

Scarab终极教程:2024年最完整的空洞骑士模组管理器使用指南

Scarab终极教程&#xff1a;2024年最完整的空洞骑士模组管理器使用指南 【免费下载链接】Scarab An installer for Hollow Knight mods written with Avalonia. 项目地址: https://gitcode.com/gh_mirrors/sc/Scarab 还在为空洞骑士模组安装而烦恼吗&#xff1f;Scarab模…...

基于RA4M2的便携GPS定位器开发:从硬件选型到低功耗优化全解析

1. 项目概述与核心价值最近在做一个挺有意思的小玩意儿&#xff0c;用瑞萨的RA4M2-SENSOR开发板&#xff0c;折腾出了一个巴掌大小的便携式GPS定位器。这玩意儿听起来好像没啥新鲜的&#xff0c;市面上成品一大堆&#xff0c;但自己从头到尾搭一遍&#xff0c;从选型、画板、写…...

【tomcat部署前台war包报错】

tomcat部署前台war包报错 背景&#xff1a;tomcat启动前台war包&#xff0c;由zip直接改文件后缀成war包&#xff0c;jdk8 同事好使&#xff0c;我不好使 部署平台日志&#xff1a; 报错一、正常tomcat执行时会把war包解压成对应文件夹&#xff0c;这里应该是没解压成功。没有具…...

【基于项目代码实测:XCP/CCP 模块“标定差异”全流程深度操作指南无标题】

在实际项目的 XCP/CCP 标定业务中&#xff0c;核对与同步底层内存参数是一项极其高频的操作。本指南将完全基于最新版“标定差异&#xff08;Calibration Difference&#xff09;”界面的真实功能逻辑&#xff0c;为你提供一份严谨、详细、且立即可用的三倍容量操作手册。无论你…...

老服务器CPU不支持x86-64-v2?手把手教你降级Hasura v2.24.0成功避坑

老服务器CPU不支持x86-64-v2&#xff1f;手把手教你降级Hasura v2.24.0成功避坑 当你在老旧服务器上部署Hasura时&#xff0c;突然遭遇"CPU does not support x86-64-v2"的错误提示&#xff0c;这可能是最令人沮丧的时刻之一。这种情况通常发生在使用较老CPU架构的物…...

BurpBounty入门指南:如何快速提升Burp Suite扫描能力

BurpBounty入门指南&#xff1a;如何快速提升Burp Suite扫描能力 【免费下载链接】BurpBounty Burp Bounty (Scan Check Builder in BApp Store) is a extension of Burp Suite that allows you, in a quick and simple way, to improve the active and passive scanner by mea…...

围棋AI训练新境界:5步掌握KaTrain智能陪练核心技巧

围棋AI训练新境界&#xff1a;5步掌握KaTrain智能陪练核心技巧 【免费下载链接】katrain Improve your Baduk skills by training with KataGo! 项目地址: https://gitcode.com/gh_mirrors/ka/katrain 想要在围棋对弈中快速提升水平&#xff1f;KaTrain作为一款基于Kata…...