郴州专业的网站建设,企业网站优化做法,拖拽式网站建设源码,合肥网站搜索引擎优化往期知识点记录#xff1a; 鸿蒙#xff08;HarmonyOS#xff09;应用层开发#xff08;北向#xff09;知识点汇总 鸿蒙#xff08;OpenHarmony#xff09;南向开发保姆级知识点汇总~ 持续更新中……
基本概念
LMS全称为Lite Memory Sanitizer#xff0c;是一种实时…往期知识点记录 鸿蒙HarmonyOS应用层开发北向知识点汇总 鸿蒙OpenHarmony南向开发保姆级知识点汇总~ 持续更新中……
基本概念
LMS全称为Lite Memory Sanitizer是一种实时检测内存操作合法性的调测工具。LMS能够实时检测缓冲区溢出buffer overflow释放后使用use after free) 和重复释放double free), 在异常发生的第一时间通知操作系统结合backtrace等定位手段能准确定位到产生内存问题的代码行极大提升内存问题定位效率。
OpenHarmony LiteOS-A内核的LMS模块提供下面几种功能 支持多内存池检测 支持LOS_MemAlloc、LOS_MemAllocAlign、LOS_MemRealloc申请出的内存检测 支持安全函数的访问检测默认开启 支持libc 高频函数的访问检测包括memset、memcpy、memmove、strcat、strcpy、strncat、strncpy。
运行机制
LMS使用影子内存映射标记系统内存的状态一共可标记为三个状态可读写不可读写已释放。影子内存存放在内存池的尾部。 内存从堆上申请后会将数据区的影子内存设置为“可读写”状态并将头节点区的影子内存设置为“不可读写”状态。 内存在堆上被释放时会将被释放内存的影子内存设置为“已释放”状态。 编译代码时会在代码中的读写指令前插入检测函数对地址的合法性进行检验。主要是检测访问内存的影子内存的状态值若检测到影子内存为不可读写则会报溢出错误若检测到影子内存为已释放则会报释放后使用错误。 在内存释放时会检测被释放地址的影子内存状态值若检测到影子内存非可读写则会报重复释放错误。
接口说明
内核态
OpenHarmony LiteOS-A内核的LMS模块提供下面几种功能接口详细信息可以查看 API 参考。
表1 LMS模块接口说明
功能分类接口名描述添加指定内存池被检测LOS_LmsCheckPoolAdd将指定内存池的地址范围添加到LMS的内存检测链表上当访问的地址在链表范围内时LMS才进行合法性校验且LOS_MemInit接口会调用该接口默认将初始化的内存池挂入到检测链表中。删除指定内存池不被检测LOS_LmsCheckPoolDel不检测指定内存池地址范围内的合法性校验。使能指定内存段锁保护LOS_LmsAddrProtect为某段内存地址上锁设置为不可读写一旦访问则报错。去能指定内存段锁保护LOS_LmsAddrDisableProtect为某段内存地址解锁设置为可读写。
用户态
用户态仅提供LMS检测库不提供对外接口。
开发指导
内核态开发流程
开启LMS调测的典型流程如下 配置LMS模块相关宏。 配置LMS控制宏LOSCFG_KERNEL_LMS默认关在kernel/liteos_a目录下执行 make update_config命令配置Kernel-Enable Lite Memory Sanitizer中打开YES 宏menuconfig选项含义取值LOSCFG_KERNEL_LMSEnable Lms FeatureLms模块的裁剪开关YES/NOLOSCFG_LMS_MAX_RECORD_POOL_NUMLms check pool max numLMS支持的检测内存池最大个数INTLOSCFG_LMS_LOAD_CHECKEnable lms read checkLMS内存读检测的裁剪开关YES/NOLOSCFG_LMS_STORE_CHECKEnable lms write checkLMS内存写检测的裁剪开关YES/NOLOSCFG_LMS_CHECK_STRICTEnable lms strict check, byte-by-byteLMS内存逐字节严格检测的裁剪开关YES/NO 在被检测模块的编译脚本中修改编译选项。 增加LMS检测编译选项-fsanitizekernel-address。为避免编译器优化增加-O0编译选项。 gcc与clang编译选项存在差异参照如下示例 if ($ohos_build_compiler_specified gcc) {cflags_c [-O0,-fsanitizekernel-address,]
} else {cflags_c [-O0,-fsanitizekernel-address,-mllvm,-asan-instrumentation-with-call-threshold0,-mllvm,-asan-stack0,-mllvm,-asan-globals0,]
}重新编译查看串口输出。如果检测到内存问题会输出检测结果。
内核态编程实例
本实例实现如下功能 创建一个用于Lms测试的任务。 构造内存溢出错误和释放后使用错误。 添加-fsanitizekernel-address后编译执行观察输出结果。
内核态示例代码
该示例代码的测试函数可以加在 kernel /liteos_a/testsuites /kernel /src /osTest.c 中的 TestTaskEntry 中进行测试。 实例代码如下
#define PAGE_SIZE (0x1000U)
#define INDEX_MAX 20
UINT32 g_lmsTestTaskId;
char g_testLmsPool[2 * PAGE_SIZE];
STATIC VOID testPoolInit(void)
{UINT32 ret LOS_MemInit(g_testLmsPool, 2 * PAGE_SIZE);if (ret ! 0) {PRINT_ERR(%s failed, ret 0x%x\n, __FUNCTION__, ret);return;}
}
static VOID LmsTestOsmallocOverflow(VOID)
{PRINTK(\n######%s start ######\n, __FUNCTION__);UINT32 i;CHAR *str (CHAR *)LOS_MemAlloc(g_testLmsPool, INDEX_MAX);PRINTK(str[%2d]0x%2x , INDEX_MAX, str[INDEX_MAX]); /* trigger heap overflow at str[INDEX_MAX] */PRINTK(\n######%s stop ######\n, __FUNCTION__);
}
static VOID LmsTestUseAfterFree(VOID)
{PRINTK(\n######%s start ######\n, __FUNCTION__);UINT32 i;CHAR *str (CHAR *)LOS_MemAlloc(g_testLmsPool, INDEX_MAX);(VOID)LOS_MemFree(g_testLmsPool, str);PRINTK(str[%2d]0x%2x , 0, str[0]); /* trigger use after free at str[0] */PRINTK(\n######%s stop ######\n, __FUNCTION__);
}
VOID LmsTestCaseTask(VOID)
{testPoolInit();LmsTestOsmallocOverflow();LmsTestUseAfterFree();
}
UINT32 Example_Lms_test(VOID)
{UINT32 ret;TSK_INIT_PARAM_S lmsTestTask;/* 创建用于lms测试的任务 */memset(lmsTestTask, 0, sizeof(TSK_INIT_PARAM_S));lmsTestTask.pfnTaskEntry (TSK_ENTRY_FUNC)LmsTestCaseTask;lmsTestTask.pcName TestLmsTsk; /* 测试任务名称 */lmsTestTask.uwStackSize 0x800; // 0x800: lms test task stack sizelmsTestTask.usTaskPrio 5; // 5: lms test task prioritylmsTestTask.uwResved LOS_TASK_STATUS_DETACHED;ret LOS_TaskCreate(g_lmsTestTaskId, lmsTestTask);if (ret ! LOS_OK) {PRINT_ERR(LmsTestTask create failed .\n);return LOS_NOK;}return LOS_OK;
}
LOS_MODULE_INIT(Example_Lms_test, LOS_INIT_LEVEL_KMOD_EXTENDED);
c内核态结果验证
输出结果如下
######LmsTestOsmallocOverflow start ######
[ERR][KProcess:LmsTestCaseTask]* Kernel Address Sanitizer Error Detected Start *
[ERR][KProcess:LmsTestCaseTask]Heap buffer overflow error detected
[ERR][KProcess:LmsTestCaseTask]Illegal READ address at: [0x4157a3c8]
[ERR][KProcess:LmsTestCaseTask]Shadow memory address: [0x4157be3c : 4] Shadow memory value: [2]
OsBackTrace fp 0x402c0f88
runTask-taskName LmsTestCaseTask
runTask-taskID 2
***backtrace begin***
traceback fp fixed, trace using fp 0x402c0fd0
traceback 0 -- lr 0x400655a4 fp 0x402c0ff8
traceback 1 -- lr 0x40065754 fp 0x402c1010
traceback 2 -- lr 0x40044bd0 fp 0x402c1038
traceback 3 -- lr 0x40004e14 fp 0xcacacaca
[LMS] Dump info around address [0x4157a3c8]:[0x4157a3a0]: 00 00 00 00 00 00 00 00 | [0x4157be3a | 0]: 1 1[0x4157a3a8]: ba dc cd ab 00 00 00 00 | [0x4157be3a | 4]: 2 2[0x4157a3b0]: 20 00 00 80 00 00 00 00 | [0x4157be3b | 0]: 2 0[0x4157a3b8]: 00 00 00 00 00 00 00 00 | [0x4157be3b | 4]: 0 0[0x4157a3c0]: 00 00 00 00 00 00 00 00 | [0x4157be3c | 0]: 0 0[0x4157a3c8]: [ba] dc cd ab a8 a3 57 41 | [0x4157be3c | 4]: [2] 2[0x4157a3d0]: 2c 1a 00 00 00 00 00 00 | [0x4157be3d | 0]: 2 3[0x4157a3d8]: 00 00 00 00 00 00 00 00 | [0x4157be3d | 4]: 3 3[0x4157a3e0]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 0]: 3 3[0x4157a3e8]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 4]: 3 3[0x4157a3f0]: 00 00 00 00 00 00 00 00 | [0x4157be3f | 0]: 3 3
[ERR][KProcess:LmsTestCaseTask]* Kernel Address Sanitizer Error Detected End *
str[20]0xffffffba
######LmsTestOsmallocOverflow stop ######
###### LmsTestUseAfterFree start ######
[ERR][KProcess:LmsTestCaseTask]* Kernel Address Sanitizer Error Detected Start *
[ERR][KProcess:LmsTestCaseTask]Use after free error detected
[ERR][KProcess:LmsTestCaseTask]Illegal READ address at: [0x4157a3d4]
[ERR][KProcess:LmsTestCaseTask]Shadow memory address: [0x4157be3d : 2] Shadow memory value: [3]
OsBackTrace fp 0x402c0f90
runTask-taskName LmsTestCaseTask
runTask-taskID 2
***backtrace begin***
traceback fp fixed, trace using fp 0x402c0fd8
traceback 0 -- lr 0x40065680 fp 0x402c0ff8
traceback 1 -- lr 0x40065758 fp 0x402c1010
traceback 2 -- lr 0x40044bd0 fp 0x402c1038
traceback 3 -- lr 0x40004e14 fp 0xcacacaca
[LMS] Dump info around address [0x4157a3d4]:[0x4157a3a8]: ba dc cd ab 00 00 00 00 | [0x4157be3a | 4]: 2 2[0x4157a3b0]: 20 00 00 80 00 00 00 00 | [0x4157be3b | 0]: 2 0[0x4157a3b8]: 00 00 00 00 00 00 00 00 | [0x4157be3b | 4]: 0 0[0x4157a3c0]: 00 00 00 00 00 00 00 00 | [0x4157be3c | 0]: 0 0[0x4157a3c8]: ba dc cd ab a8 a3 57 41 | [0x4157be3c | 4]: 2 2[0x4157a3d0]: 2c 1a 00 00 [00] 00 00 00 | [0x4157be3d | 0]: 2 [3][0x4157a3d8]: 00 00 00 00 00 00 00 00 | [0x4157be3d | 4]: 3 3[0x4157a3e0]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 0]: 3 3[0x4157a3e8]: ba dc cd ab c8 a3 57 41 | [0x4157be3e | 4]: 2 2[0x4157a3f0]: 0c 1a 00 00 00 00 00 00 | [0x4157be3f | 0]: 2 3[0x4157a3f8]: 00 00 00 00 00 00 00 00 | [0x4157be3f | 4]: 3 3
[ERR][KProcess:LmsTestCaseTask]* Kernel Address Sanitizer Error Detected End *
str[ 0]0x 0
######LmsTestUseAfterFree stop ######
输出的关键信息包括 错误类型 Heap buffer overflow堆内存越界Use after free 释放后使用 错误操作 Illegal Read非法读Illegal Write非法写Illegal Double free重复释放 上下文 当前任务信息taskName taskId回溯栈(backtrace) 出错地址的内存信息 内存的值、及对应影子内存的值内存地址内存值| [影子内存地址 | 影子内存字节内偏移]:影子内存值影子内存值0可读可写、3已释放、2红区、1填充值。
用户态开发流程
在待检测的app编译脚本中添加如下参数即可 完整示例可参见 /kernel/liteos_a/apps/lms/BUILD.gn。
if ($ohos_build_compiler_specified gcc) {cflags_c [-O0,-fsanitizekernel-address,-funwind-tables,-fasynchronous-unwind-tables,]} else {cflags_c [-O0,-fsanitizekernel-address,-mllvm,-asan-instrumentation-with-call-threshold0,-mllvm,-asan-stack0,-mllvm,-asan-globals0,-funwind-tables,-fasynchronous-unwind-tables,]}ldflags [-rdynamic,-lunwind,-lusrlms,-Wl,--wraprealloc,-Wl,--wrapcalloc,-Wl,--wrapmalloc,-Wl,--wrapfree,-Wl,--wrapvalloc,-Wl,--wrapaligned_alloc,-Wl,--wrapmemset,-Wl,--wrapmemcpy,-Wl,--wrapmemmove,-Wl,--wrapstrcpy,-Wl,--wrapstrcat,]deps [ //kernel/liteos_a/kernel/extended/lms/usr:usrlmslib ]
用户态编程实例
本实例实现如下功能 构造内存溢出错误和释放后使用错误。 添加对应编译选项后重新编译执行。
用户态示例代码
实例代码如下
static void BufWriteTest(void *buf, int start, int end)
{for (int i start; i end; i) {((char *)buf)[i] a;}
}
static void BufReadTest(void *buf, int start, int end)
{char tmp;for (int i start; i end; i) {tmp ((char *)buf)[i];}
}
static void LmsMallocTest(void)
{printf(\n-------- LmsMallocTest Start --------\n);char *buf (char *)malloc(16); // 16: buffer size for testBufReadTest(buf, -1, 16);free(buf);printf(\n-------- LmsMallocTest End --------\n);
}
static void LmsFreeTest(void)
{printf(\n-------- LmsFreeTest Start --------\n);char *buf (char *)malloc(16); // 16: buffer size for testfree(buf);BufReadTest(buf, 1, 1);free(buf);printf(\n-------- LmsFreeTest End --------\n);
}
int main(int argc, char * const * argv)
{printf(\n############### Lms Test start ###############\n);char *tmp (char *)malloc(5000); // 5000: temp buffer sizeLmsMallocTest();LmsFreeTest();printf(\n############### Lms Test End ###############\n);
}
c用户态结果验证
输出结果如下
* Lite Memory Sanitizer Error Detected *
Heap buffer overflow error detected!
Illegal READ address at: [0x1f8b3edf]
Shadow memory address: [0x3d34d3ed : 6] Shadow memory value: [2]
Accessible heap addr 0
Heap red zone 2
Heap freed buffer 3
Dump info around address [0x1f8b3edf]:[0x1f8b3eb8]: 74 55 8b 1f 74 55 8b 1f | [0x3d34d3eb | 4]: 0 0[0x1f8b3ec0]: f8 9c 8b 1f 00 00 00 00 | [0x3d34d3ec | 0]: 0 0[0x1f8b3ec8]: 00 00 00 00 9c fc fc fc | [0x3d34d3ec | 4]: 0 0[0x1f8b3ed0]: 21 00 00 00 41 00 00 00 | [0x3d34d3ed | 0]: 0 0[0x1f8b3ed8]: 60 55 8b 1f 60 55 8b [1f]| [0x3d34d3ed | 4]: 2 [2][0x1f8b3ee0]: 50 4e 0b 00 00 00 00 00 | [0x3d34d3ee | 0]: 0 0[0x1f8b3ee8]: 09 00 00 00 00 00 00 00 | [0x3d34d3ee | 4]: 0 0[0x1f8b3ef0]: 00 00 00 00 08 03 09 00 | [0x3d34d3ef | 0]: 2 2[0x1f8b3ef8]: 00 00 00 00 00 00 00 00 | [0x3d34d3ef | 4]: 2 2
* Lite Memory Sanitizer Error Detected End *
Backtrace() returned 5 addresses#01: LMS_ReportError0x284[0x4d6c] - ./sample_usr_lms#02: (null)0x2004074[0x4074] - ./sample_usr_lms#03: (null)0x2003714[0x3714] - ./sample_usr_lms#04: main0x40[0x363c] - ./sample_usr_lms#05: (null)0x1f856f30[0x56f30] - /lib/libc.so
-------- LMS_malloc_test End --------
* Lite Memory Sanitizer Error Detected *
Use after free error detected!
Illegal Double free address at: [0x1f8b3ee0]
Shadow memory address: [0x3d34d3ee : 0] Shadow memory value: [3]
Accessible heap addr 0
Heap red zone 2
Heap freed buffer 3
Dump info around address [0x1f8b3ee0]:[0x1f8b3ec0]: f8 9c 8b 1f 00 00 00 00 | [0x3d34d3ec | 0]: 0 0[0x1f8b3ec8]: 00 00 00 00 fc fd fc fc | [0x3d34d3ec | 4]: 0 0[0x1f8b3ed0]: 21 00 00 00 20 01 00 00 | [0x3d34d3ed | 0]: 0 0[0x1f8b3ed8]: 60 55 8b 1f 60 55 8b 1f | [0x3d34d3ed | 4]: 2 2[0x1f8b3ee0]: [20] 60 9a 1f 40 61 9a 1f | [0x3d34d3ee | 0]: [3] 3[0x1f8b3ee8]: 60 62 9a 1f 80 63 9a 1f | [0x3d34d3ee | 4]: 3 3[0x1f8b3ef0]: 20 40 8b 1f 20 20 8b 1f | [0x3d34d3ef | 0]: 3 3[0x1f8b3ef8]: 00 00 00 00 00 00 00 00 | [0x3d34d3ef | 4]: 3 3[0x1f8b3f00]: 00 00 00 00 00 00 00 00 | [0x3d34d3f0 | 0]: 3 3
* Lite Memory Sanitizer Error Detected End *
Backtrace() returned 5 addresses#01: LMS_ReportError0x284[0x4d6c] - ./sample_usr_lms#02: LMS_free0xcc[0x5548] - ./sample_usr_lms#03: (null)0x2003fc4[0x3fc4] - ./sample_usr_lms#04: main0x68[0x3664] - ./sample_usr_lms#05: (null)0x1f856f30[0x56f30] - /lib/libc.so
-------- LMS_free_test End --------
输出的Backtrace中包含地址所在的文件名用户需查找对应文件中地址对应的代码行号。
最后
经常有很多小伙伴抱怨说不知道学习鸿蒙开发哪些技术不知道需要重点掌握哪些鸿蒙应用开发知识点
为了能够帮助到大家能够有规划的学习这里特别整理了一套纯血版鸿蒙HarmonyOS Next全栈开发技术的学习路线包含了鸿蒙开发必掌握的核心知识要点内容有ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等鸿蒙HarmonyOS NEXT技术知识点。 《鸿蒙 (Harmony OS)开发学习手册》共计892页:https://gitcode.com/HarmonyOS_MN/733GH/overview
如何快速入门
1.基本概念 2.构建第一个ArkTS应用 3.…… 鸿蒙开发面试真题含参考答案: 《OpenHarmony源码解析》:
搭建开发环境Windows 开发环境的搭建Ubuntu 开发环境搭建Linux 与 Windows 之间的文件共享……系统架构分析构建子系统启动流程子系统分布式任务调度子系统分布式通信子系统驱动子系统…… OpenHarmony 设备开发学习手册:https://gitcode.com/HarmonyOS_MN/733GH/overview