HarmonyOS鸿蒙Next中到底是我写的有问题,还是你们的文档代码有问题?做一个代码移植就这么难吗?
HarmonyOS鸿蒙Next中到底是我写的有问题,还是你们的文档代码有问题?做一个代码移植就这么难吗? 简单函数:
char* getAppPackageName(){
OH_NativeBundle_ApplicationInfo nativeApplicationInfo = OH_NativeBundle_GetCurrentApplicationInfo();
//获取当前应用的application信息
char* packageName = nativeApplicationInfo.bundleName;
//获取存储包名的指针信息
size_t nameLength = std::strlen(packageName);
//获取包名的字符长度
char* packageNameReal = new char[nameLength+1];
//heap堆上申请一块新内存,来存储包名,并获得新内存的起始地址,这里长度加1是留给'\0'
for(int i=0;i<nameLength;i++){
//通过for循环,将package name 复制到新新创建的内存里面
*(packageNameReal+i) = *(packageName+i);
}
*(packageNameReal+nameLength) = '\0';
//字符结束,一定要加上空字符
return packageNameReal;
}
调用代码:
static napi_value NAPI_Global_nativeGenerateSecret(napi_env env, napi_callback_info info) {
// TODO: implements the code;
bool isDebug = false;
OH_NativeBundle_IsDebugMode(&isDebug);
OH_LOG_INFO(LOG_APP, "path: %{public}s", isDebug?"True":"False");
char* packageName = getAppPackageName();
OH_LOG_INFO(LOG_APP, "path: %{public}s", packageName);
napi_value str;
napi_create_string_utf8(env, packageName, NAPI_AUTO_LENGTH, &str);
delete [] packageName;
return str;
}
在app.json5配置里:
"asanEnabled": true,
在模块的build-profile.json5配置:
"arguments": "-DOHOS_ENABLE_ASAN=ON"
上面的函数就要报错,应用直接崩溃。
但是下面这样设置,屁事没有:
“asanEnabled”: false
“arguments”: “”
报错的内容:
Device info:emulator
Build info:emulator 6.0.0.112(SP3DEVC00E112R4P11)
Fingerprint:c073f772f2da56c0d4b419efbe1f6bcd344f7fa0f5765adc21f73433fcd36343
Timestamp:2025-12-30 19:13:01.393
Module name:com.sshy.aiblindbox
Version:1.0.0
Pid:12500
Uid:20020057
Reason:heap-use-after-free
=================================================================
==appspawn==12500==ERROR: AddressSanitizer: heap-use-after-free on address 0x603001275820 at pc 0x7f536f7467bb bp 0x7ffe86e4fa30 sp 0x7ffe86e4f1f8
READ of size 4 at 0x603001275820 thread T0 (sshy.aiblindbox)
#0 0x7f536f7467ba (/system/lib64/libclang_rt.asan.so+0x867ba) (BuildId: 7426e27426124e4ca93655f0287fb4c991a96f17)
#1 0x7f531b745294 (/data/storage/el1/bundle/libs/x86_64/libentry.so+0x5294) (BuildId: 5f386d13a75aa7ccac983ebee5bfb4ce5331ce80)
#2 0x7f531b746486 (/data/storage/el1/bundle/libs/x86_64/libentry.so+0x6486) (BuildId: 5f386d13a75aa7ccac983ebee5bfb4ce5331ce80)
#3 0x7f536ac541f0 (/system/lib64/platformsdk/libace_napi.z.so+0x541f0) (BuildId: 762c76a538c75db479d337795e7c7fab)
0x603001275820 is located 0 bytes inside of 20-byte region [0x603001275820,0x603001275834)
freed by thread T0 (sshy.aiblindbox) here:
#0 0x7f536f7a1e7b (/system/lib64/libclang_rt.asan.so+0xe1e7b) (BuildId: 7426e27426124e4ca93655f0287fb4c991a96f17)
#1 0x7f531b7230b2 (/system/lib64/libbundle_ndk.z.so+0x230b2) (BuildId: c78f124221c904bc126d835538c845fd)
#2 0x7f531b746486 (/data/storage/el1/bundle/libs/x86_64/libentry.so+0x6486) (BuildId: 5f386d13a75aa7ccac983ebee5bfb4ce5331ce80)
#3 0x7f536ac541f0 (/system/lib64/platformsdk/libace_napi.z.so+0x541f0) (BuildId: 762c76a538c75db479d337795e7c7fab)
previously allocated by thread T0 (sshy.aiblindbox) here:
#0 0x7f536f7a1fad (/system/lib64/libclang_rt.asan.so+0xe1fad) (BuildId: 7426e27426124e4ca93655f0287fb4c991a96f17)
#1 0x7f531b722fae (/system/lib64/libbundle_ndk.z.so+0x22fae) (BuildId: c78f124221c904bc126d835538c845fd)
#2 0x7f531b746486 (/data/storage/el1/bundle/libs/x86_64/libentry.so+0x6486) (BuildId: 5f386d13a75aa7ccac983ebee5bfb4ce5331ce80)
#3 0x7f536ac541f0 (/system/lib64/platformsdk/libace_napi.z.so+0x541f0) (BuildId: 762c76a538c75db479d337795e7c7fab)
SUMMARY: AddressSanitizer: heap-use-after-free (/system/lib64/libclang_rt.asan.so+0x867ba) (BuildId: 7426e27426124e4ca93655f0287fb4c991a96f17)
Shadow bytes around the buggy address:
0x0c0680246ab0: fd fd fd fa fa fa fd fd fd fa fa fa fd fd fd fa
0x0c0680246ac0: fa fa fd fd fd fa fa fa fd fd fd fa fa fa fd fd
0x0c0680246ad0: fd fa fa fa fd fd fd fa fa fa fd fd fd fa fa fa
0x0c0680246ae0: fd fd fd fa fa fa fd fd fd fa fa fa fd fd fd fa
0x0c0680246af0: fa fa fd fd fd fa fa fa fd fd fd fa fa fa fd fd
=>0x0c0680246b00: fd fa fa fa[fd]fd fd fa fa fa fa fa fa fa fa fa
0x0c0680246b10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0680246b20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0680246b30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0680246b40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0680246b50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==appspawn==12500==ABORTING
==appspawn==12500==Process memory map follows:
0x000040a44000-0x000040a48000 /data/storage/el1/bundle/entry.hap
0x00007fff7000-0x00008fff7000 [anon:low shadow]
0x00008fff7000-0x02008fff7000 [anon:shadow gap]
0x02008fff7000-0x0feae3630000 [anon:high shadow]
0x0feae3630000-0x0feae364f000
0x0feae364f000-0x0feae3650000 [anon:high shadow]
0x0feae3650000-0x0feae366f000
0x0feae366f000-0x0feae36f5000 [anon:high shadow]
0x0feae36f5000-0x0feae3714000
0x0feae3714000-0x0feae3716000 [anon:high shadow]
0x0feae3716000-0x0feae3735000
0x0feae3735000-0x0feae3736000 [anon:high shadow]
0x0feae3736000-0x0feae3755000
0x0feae3755000-0x0feae3756000 [anon:high shadow]
0x0feae3756000-0x0feae3776000
0x0feae3776000-0x0feae3777000 [anon:high shadow]
0x0feae3777000-0x0feae3796000
0x0feae3796000-0x0feae3797000 [anon:high shadow]
0x0feae3797000-0x0feae37b6000
0x0feae37b6000-0x0feae37b8000 [anon:high shadow]
0x0feae37b8000-0x0feae37d7000
0x0feae37d7000-0x0feae37d8000 [anon:high shadow]
0x0feae37d8000-0x0feae37f7000
0x0feae37f7000-0x0feae37f8000 [anon:high shadow]
0x0feae37f8000-0x0feae3817000
0x0feae3817000-0x0feae3828000 [anon:high shadow]
0x0feae3828000-0x0feae3847000
0x0feae3847000-0x0feae386f000 [anon:high shadow]
0x0feae386f000-0x0feae388e000
0x0feae388e000-0x0feae3890000 [anon:high shadow]
0x0feae3890000-0x0feae38af000
0x0feae38af000-0x0feae38b0000 [anon:high shadow]
0x0feae38b0000-0x0feae38cf000
0x0feae38cf000-0x0feae38d0000 [anon:high shadow]
0x0feae38d0000-0x0feae38ef000
0x0feae38ef000-0x0feae3956000 [anon:high shadow]
0x0feae3956000-0x0feae3975000
0x0feae3975000-0x0feae3976000 [anon:high shadow]
0x0feae3976000-0x0feae3995000
0x0feae3995000-0x0feae3996000 [anon:high shadow]
0x0feae3996000-0x0feae39b5000
0x0feae39b5000-0x0feae39b6000 [anon:high shadow]
0x0feae39b6000-0x0feae39d6000
0x0feae39d6000-0x0feae39d7000 [anon:high shadow]
0x0feae39d7000-0x0feae39f6000
0x0feae39f6000-0x0feae39f7000 [anon:high shadow]
0x0feae39f7000-0x0feae3a16000
0x0feae3a16000-0x0feae3b18000 [anon:high shadow]
0x0feae3b18000-0x0feae3b37000
0x0feae3b37000-0x0feae3b38000 [anon:high shadow]
0x0feae3b38000-0x0feae3b57000
0x0feae3b57000-0x0feae3b58000 [anon:high shadow]
0x0feae3b58000-0x0feae3b77000
0x0feae3b77000-0x0feae3b87000 [anon:high shadow]
0x0feae3b87000-0x0feae3ba7000
0x0feae3ba7000-0x0feae3ba8000 [anon:high shadow]
0x0feae3ba8000-0x0feae3bc7000
0x0feae3bc7000-0x0feae3bc8000 [anon:high shadow]
0x0feae3bc8000-0x0feae3be7000
0x0feae3be7000-0x0feae3be9000 [anon:high shadow]
0x0feae3be9000-0x0feae3c08000
0x0feae3c08000-0x0feae4481000 [anon:high shadow]
0x0feae4481000-0x0feae4490000
0x0feae4490000-0x0feae4491000 [anon:high shadow]
0x0feae4491000-0x0feae44a1000
0x0feae44a1000-0x0feae471f000 [anon:high shadow]
0x0feae471f000-0x0feae473e000
0x0feae473e000-0x0feae473f000 [anon:high shadow]
0x0feae473f000-0x0feae475e000
0x0feae475e000-0x0feae4760000 [anon:high shadow]
0x0feae4760000-0x0feae47bf000
0x0feae47bf000-0x0feaeaefe000 [anon:high shadow]
0x0feaeaefe000-0x0feaeafaf000
0x0feaeafaf000-0x100050cc4000 [anon:high shadow]
0x100050cc4000-0x100050dc3000
0x100050dc3000-0x10007fff8000 [anon:high shadow]
0x55c51f92f000-0x55c51f93d000 /system/bin/appspawn
0x55c51f93d000-0x55c51f94e000 /system/bin/appspawn
0x55c51f94e000-0x55c51f94f000 /system/bin/appspawn
0x55c51f94f000-0x55c51f950000 /system/bin/appspawn
0x55c52150c000-0x55c52150d000 [heap]
0x55c52150d000-0x55c521517000 [heap]
0x600000000000-0x602000000000 [anon:SizeClassAllocator]
0x602000000000-0x602001260000 [anon:SizeClassAllocator: region data]
0x602001260000-0x602e00000000 [anon:SizeClassAllocator]
0x602e00000000-0x602e00010000 [anon:SizeClassAllocator: freearray]
0x602e00010000-0x603000000000 [anon:SizeClassAllocator]
0x603000000000-0x603001300000 [anon:SizeClassAllocator: region data更多关于HarmonyOS鸿蒙Next中到底是我写的有问题,还是你们的文档代码有问题?做一个代码移植就这么难吗?的实战教程也可以访问 https://www.itying.com/category-93-b0.html
你写的有问题 不难啊
更多关于HarmonyOS鸿蒙Next中到底是我写的有问题,还是你们的文档代码有问题?做一个代码移植就这么难吗?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
鸿蒙Next的API和架构与之前版本有差异,直接移植代码可能不兼容。请检查是否使用了已废弃的接口或未适配新框架。建议查阅最新的HarmonyOS Next官方文档,确认API调用方式。
根据你提供的代码和报错信息,问题出在 getAppPackageName 函数的内存管理上。AddressSanitizer (ASAN) 检测到了 heap-use-after-free 错误,即内存被释放后又被访问。
根本原因分析:
OH_NativeBundle_GetCurrentApplicationInfo返回的结构体:nativeApplicationInfo.bundleName指针指向的内存是由系统API内部管理的。你的代码假设这个指针指向的是一个你可以安全持有并随后进行strlen操作的、以空字符结尾的字符串。- 生命周期问题:
OH_NativeBundle_ApplicationInfo结构体(及其内部的bundleName指针)很可能在OH_NativeBundle_GetCurrentApplicationInfo函数调用结束后就失效了,或者其内存所有权有特殊的规则。你的代码在获取该指针后,又在其可能失效的上下文中使用它(进行字符串复制),导致了释放后使用。
错误复现路径(推测):
- 系统API
OH_NativeBundle_GetCurrentApplicationInfo在栈上或某个临时内存区填充了OH_NativeBundle_ApplicationInfo结构体,bundleName指向该区域内的一个字符串。 - 你的函数返回后,该临时内存区被回收或标记为可释放。
- 随后,你的
std::strlen(packageName)或napi_create_string_utf8尝试读取这块已释放的内存,触发ASAN报错。
解决方案:
不要直接复制 bundleName 指针,而是应该在 OH_NativeBundle_GetCurrentApplicationInfo 调用后,立即将字符串内容复制到你自己管理的内存中。查阅HarmonyOS NDK文档,确认 OH_NativeBundle_ApplicationInfo 及其字段的确切生命周期和内存所有权。通常,对于这类返回字符串指针的API,需要立即进行深拷贝。
一个更安全的 getAppPackageName 函数实现示例如下(需根据实际API调整):
char* getAppPackageName() {
OH_NativeBundle_ApplicationInfo nativeApplicationInfo = OH_NativeBundle_GetCurrentApplicationInfo();
// 立即获取原始指针和长度
const char* bundleName = nativeApplicationInfo.bundleName;
if (!bundleName) {
return nullptr;
}
// 计算长度(假设bundleName是有效的C字符串)
size_t nameLength = std::strlen(bundleName);
// 分配新内存
char* packageNameReal = new char[nameLength + 1];
// 复制字符串内容
std::strcpy(packageNameReal, bundleName);
// 返回新分配的内存,调用者负责释放
return packageNameReal;
}
关键点:
bundleName被当作一个临时指针,仅用于立即的strlen和strcpy操作。- 所有后续操作都使用你自己分配的
packageNameReal内存。 - 调用者(
NAPI_Global_nativeGenerateSecret)在napi_create_string_utf8后使用delete[]释放内存是正确的。
当关闭ASAN时,内存错误可能未被立即检测到,程序看似“正常”,但这掩盖了潜在的崩溃风险。ASAN报告准确地指出了问题所在:代码存在对已释放堆内存的访问。修复内存管理逻辑即可解决此问题。

