ASan和HWAsan在Android中使用

这篇具有很好参考价值的文章主要介绍了ASan和HWAsan在Android中使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. ASan和HWAsan比较

ASan

HWASan

全称

Address Sanitizer

Hardware-assisted AddressSanitizer

版本

可以在32位和64位的x86、x86-64上。

从API 27(Android O MR 1)开始,Android NDK 可支持ASAN。

在Android 11 之后的AOSP master中,弃用了arm64 上的平台开发ASan,改为使用HWASan。

只在Android 10 及以上版本有效,且只使用于AArch64硬件平台。

检测bugs

Stack and heap buffer overflow/underflow

Heap use after free

Stack use outside scope

Double free/wild free

Stack and heap buffer overflow/underflow

Heap use after free

Stack use outside scope

Double free/wild free

stack use after return

要求

CPU 开销(~ 2倍)

代码大小开销(50% ~ 2倍)

内存开销(~ 2倍)

CPU 开销(~ 2倍)

代码大小开销(40% ~ 50%)

内存开销(10% ~ 35%)

原理

使用shadow memory(内存的一个区域)内存状态进行标记,如free掉的内存在shadow中标记为0xfd,已经申请的内存,前后存在安全区标记为0xfa

AArch64是64位的架构,一个64bit的指针值,其中真正用于寻址的只有低48位。

AArch64拥有地址标记(Address tagging, or top-byte-ignore)的特性,它表示允许软件使用64bit指针值的高8位开发特定功能。HWASAN用这8bit来存储一块内存区域的标签(tag)。

缺点

1)ASAN的运行是需要消耗memory和CPU资源的,此外它也会增加代码大小。它的性能相比于之前的工具确实有了质的提升,但仍然无法适用于某些压力测试场景,尤其是需要全局打开的时候。这一点在Android上尤为明显,每当我们想要全局打开ASAN调试某些奇葩问题时,系统总会因为负载过重而跑不起来;

2)对于 free 的内存标记存在隔离时间,即 free 的区域一段时间后重新分配其他所有者,此时原持有者访问不会报错;

3)对应flow的安全区总归有大小,如果踩踏过了安全区,同样不会报错;

1)可移植性差,只用于64位平台;

2)需要对Linux Kernel做一些改动以支持工具

3)对于所有错误的检测将有一定概率false negative(漏掉一些真实的错误),概率为1/256。原因是tag的生成只能从256(2的8次方)个数中选一个,因此不同地址的tag将有可能相同

优点

比较ASan:

1)不再需要安全区来检测buffer overflow,既极大地降低了工具对于内存的消耗,也不会出现ASAN中某些overflow检测不到的情况;

2)不再需要隔离区来检测UseAfterFree,因此不会出现ASAN中某些UseAfterFree检测不到的情况

2. ASan 编译

2.1 整体编译

m -j16
SANITIZE_TARGET=address m -j16

注意,这里需要两次编译。第一次是为了在 /system/lib 中编译常规库,第二次编译是为了在 /system/lib/asan 中进行 ASan 插桩。 

需要刷新system、vendor、system分区,因为上述第 2 步编译ASAN库在/data/asan目录下。

2.2 单独编译

Android.mk
LOCAL_SANITIZE := address
 
Android.bp
sanitize: { address: true }

2.2.1 编译共享库

LOCAL_SANITIZE:=address
LOCAL_MODULE_RELATIVE_PATH := asan

这样一来,系统会将库放到 /system/lib/asan 中而非 /system/lib 中。但是需要指定库的路径方便链接:

LD_LIBRARY_PATH=/system/lib/asan
或
setenv LD_LIBRARY_PATH /system/lib/asan

通过 /proc/PID/maps 验证使用的库是否来自 /system/lib/asan(如果此库存在),如果不是,可能需要停用 selinux:

adb root
adb shell setenforce 0
# restart the process with adb shell kill $PID
# if it is a system service, or may be adb shell stop; adb shell start.

2.3 无法使用ASan构建

有些目标无法使用ASan 构建:

  • 静态关联的可执行文件
  • LOCA_CLANG:=false 目标
  • 不会针对 SANITIZE_TARGET=address进行ASan 操作的LOCAL_SANITIZE:=false 的目标

在 SANITIZE_TARGET build 中,系统会跳过此类可执行文件,且会将第一个make 调用中构建的版本留在 /system/bin 中。

3. HWASan 编译

3.1 整体编译

export SANITIZE_TARGET=hwaddress
m -j16

与ASan 不同,HWASan 无需构建两次,只需增量构建,没有特殊的刷写指令,不需要擦除,支持静态可执行文件,并且可以跳过除 libc 之外的任何库的排错。

通过环境变量 SANITIZE_TARGET 指定排错(sanitizer)。

3.2 单独编译bin/lib

在编译脚本中增加如下参数即可

Android.mk
LOCAL_SANITIZE:= hwaddress
 
Android.bp
sanitize: { hwaddress: true }

如果需要在整体构建中,去除某模块HWASAN的编译

Android.mk
LOCAL_NOSANITIZE := hwaddress
 
Android.bp
sanitize: { hwaddress: false}

4. 解析

由于版本默认库或者bin是stripped过的,因此无法解析,如

==4415==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x003a861bb057 at pc 0x00775f3c664c bp 0x007fd0f434b0 sp 0x007fd0f42c90
READ of size 8 at 0x003a861bb057 thread T0
    #0 0x775f3c6648  (/system/lib64/libclang_rt.asan-aarch64-android.so+0x72648)
    #1 0x775f3c6ff8  (/system/lib64/libclang_rt.asan-aarch64-android.so+0x72ff8)
    #2 0x59861bf0a8  (/vendor/bin/qrtr-lookup+0x20a8)
    #3 0x775f72488c  (/apex/com.android.runtime/lib64/bionic/libc.so+0x4988c)
 
0x003a861bb057 is located 0 bytes to the right of 7-byte region [0x003a861bb050,0x003a861bb057)
allocated by thread T0 here:
    #0 0x775f3f6088  (/system/lib64/libclang_rt.asan-aarch64-android.so+0xa2088)
    #1 0x59861bf094  (/vendor/bin/qrtr-lookup+0x2094)
    #2 0x775f72488c  (/apex/com.android.runtime/lib64/bionic/libc.so+0x4988c)
    #3 0x59861bf044  (/vendor/bin/qrtr-lookup+0x2044)
    #4 0x7760b9fbb4  (/vendor/bin/qrtr-lookup+0x4cbb4)
 
SUMMARY: AddressSanitizer: heap-buffer-overflow (/system/lib64/libclang_rt.asan-aarch64-android.so+0x72648)
Shadow bytes around the buggy address:
  0x001750c375b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001750c375c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001750c375d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001750c375e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001750c375f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x001750c37600: fa fa 00 fa fa fa 00 fa fa fa[07]fa fa fa fa fa
  0x001750c37610: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x001750c37620: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x001750c37630: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x001750c37640: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x001750c37650: 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
  Shadow gap:              cc
==4415==ABORTING

4.1 直接解析

  • push llvm-symbolizer到 system/bin下
    • 如 push到其他目录,需要保证该目录在PATH下或者设置环境变量export ASAN_SYMBOLIZER_PATH=/system/bin/llvm-symbolizer
    •  llvm-symbolizer路径:android\vendor\qcom\proprietary\llvm-arm-toolchain-ship\10.0\aarch64-linux-android\bin\llvm-symbolizer
  • push 对应模块带有symbols的库或者bin到对应目录,源文件位于android\out\target\product\shift\symbols

上述工作完成后,当ASAN / HWASan 检查到错误后,相关结果会自动解析到logcat 或screen 上,包括具体的函数,行号等等

==================================================================
==6646==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x003c452d8057 at pc 0x00749d4d364c bp 0x007fd09ac530 sp 0x007fd09abd10
READ of size 8 at 0x003c452d8057 thread T0
    #0 0x749d4d3648 in printf_common(void*, char const*, std::__va_list) /out/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors_format.inc:547:9
    #1 0x749d4d3ff8 in __interceptor_vprintf /out/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:1645:1
    #2 0x749d4d3ff8 in printf /out/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:1703:1
    #3 0x5b452dc1a8 in main vendor/qcom/proprietary/qmi-framework/qrtr/src/lookup.c:143:5
    #4 0x749d3a888c in __libc_init (/apex/com.android.runtime/lib64/bionic/libc.so+0x4988c)
 
0x003c452d8057 is located 0 bytes to the right of 7-byte region [0x003c452d8050,0x003c452d8057)
allocated by thread T0 here:
    #0 0x749d503088 in malloc /out/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
    #1 0x5b452dc194 in main vendor/qcom/proprietary/qmi-framework/qrtr/src/lookup.c:142:21
    #2 0x749d3a888c in __libc_init (/apex/com.android.runtime/lib64/bionic/libc.so+0x4988c)
    #3 0x5b452dc044 in _start_main bionic/libc/arch-common/bionic/crtbegin.c:45:3
    #4 0x749eb2dbb4  (/vendor/bin/qrtr-lookup+0x4cbb4)
 
SUMMARY: AddressSanitizer: heap-buffer-overflow /out/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors_format.inc:547:9 in printf_common(void*, char const*, std::__va_list)
Shadow bytes around the buggy address:
  0x001788a5afb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001788a5afc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001788a5afd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001788a5afe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x001788a5aff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x001788a5b000: fa fa 00 fa fa fa 00 fa fa fa[07]fa fa fa fa fa
  0x001788a5b010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x001788a5b020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x001788a5b030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x001788a5b040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x001788a5b050: 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
  Shadow gap:              cc
==6646==ABORTING
Aborted

4.2 编译带symbols 的lib/bin(单独模块进行排错)

  • ASAN/HWASan,push 额外libc++_shared.so
    • 命令 adb push android\prebuilts\ndk\r21\sources\cxx-stl\llvm-libc++\libs\arm64-v8a\libc++_shared.so /system/lib64
  • HWASan 需要额外push  libclang_rt.hwasan-aarch64-android.so库
    • 命令 adb push android\vendor\qcom\proprietary\llvm-arm-toolchain-ship\10.0\lib\clang\10.0.7\lib\linux\libclang_rt.hwasan-aarch64-android.so /system/lib64
  • push llvm-symbolizer到system/bin下
  • 模块的编译脚本携带如下参数
Android.mk
LOCAL_STRIP_MODULE :=false
Android.bp
strip :{keep_symbols: true,},

可得到如下信息,得到具体的函数

==10804==ERROR: HWAddressSanitizer: invalid-free on address 0x0038f7647040 at pc 0x0072ed942bb8
tags: 1a/96 (ptr/mem)
    #0 0x72ed942bb4 in __sanitizer_free /out/llvm-project/compiler-rt/lib/hwasan/hwasan_interceptors.cpp:108:3
    #1 0x57f764b0b8 in main (/vendor/bin/qrtr-lookup+0x20b8)
    #2 0x72ed831174 in __libc_init (/apex/com.android.runtime/lib64/bionic/libc.so+0x4e174)
    #3 0x57f764b044 in _start_main (/vendor/bin/qrtr-lookup+0x2044)
    #4 0x72eefd3bb4  (/vendor/bin/qrtr-lookup+0x4cbb4)
 
[0x0038f7647040,0x0038f7647060) is a small unallocated heap chunk; size: 32 offset: 0
0x0038f7647040 is located 0 bytes inside of 7-byte region [0x0038f7647040,0x0038f7647047)
freed by thread T0 here:
    #0 0x72ed942bb4 in __sanitizer_free /out/llvm-project/compiler-rt/lib/hwasan/hwasan_interceptors.cpp:108:3
    #1 0x57f764b0b0 in main (/vendor/bin/qrtr-lookup+0x20b0)
    #2 0x72ed831174 in __libc_init (/apex/com.android.runtime/lib64/bionic/libc.so+0x4e174)
    #3 0x57f764b044 in _start_main (/vendor/bin/qrtr-lookup+0x2044)
    #4 0x72eefd3bb4  (/vendor/bin/qrtr-lookup+0x4cbb4)
 
previously allocated here:
    #0 0x72ed943084 in __sanitizer_malloc /out/llvm-project/compiler-rt/lib/hwasan/hwasan_interceptors.cpp:169:3
    #1 0x72ed826bdc in malloc (/apex/com.android.runtime/lib64/bionic/libc.so+0x43bdc)
    #2 0x57f764b094 in main (/vendor/bin/qrtr-lookup+0x2094)
    #3 0x72ed831174 in __libc_init (/apex/com.android.runtime/lib64/bionic/libc.so+0x4e174)
    #4 0x57f764b044 in _start_main (/vendor/bin/qrtr-lookup+0x2044)
    #5 0x72eefd3bb4  (/vendor/bin/qrtr-lookup+0x4cbb4)
 
hwasan_dev_note_heap_rb_distance: 1 1023
Thread: T0 0x006900002000 stack: [0x007fd2fc0000,0x007fd37c0000) sz: 8388608 tls: [0x000000000000,0x000000000000)
Memory tags around the buggy address (one tag corresponds to 16 bytes):
  0x006d8f764680: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0x006d8f764690: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0x006d8f7646a0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0x006d8f7646b0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0x006d8f7646c0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0x006d8f7646d0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0x006d8f7646e0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0x006d8f7646f0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
=>0x006d8f764700: 08  00  08  00 [96] 00  00  00  00  00  00  00  00  00  00  00
  0x006d8f764710: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0x006d8f764720: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0x006d8f764730: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0x006d8f764740: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0x006d8f764750: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0x006d8f764760: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0x006d8f764770: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
  0x006d8f764780: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
Tags for short granules around the buggy address (one tag corresponds to 16 bytes):
  0x006d8f7646f0: ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
=>0x006d8f764700: e2  ..  7a  .. [..] ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
  0x006d8f764710: ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags
SUMMARY: HWAddressSanitizer: invalid-free /out/llvm-project/compiler-rt/lib/hwasan/hwasan_interceptors.cpp:108:3 in __sanitizer_free

4.3 host 解析

将dump信息copy进入文件dumpinfo,按照如下格式(===开头)

=================================================================
==24786==ERROR: AddressSanitizer: SEGV on unknown address 0x180001a46bc1c34 (pc 0x00761175f308 bp 0x007fc5f519b0 sp 0x007fc5f51970 T0)
==24786==The signal is caused by a READ memory access.
    #0 0x761175f308  (/system/system_ext/lib64/libimsmedia_jni.so+0x3308)
    #1 0x761175f1b8 in JNI_OnLoad (/system/system_ext/lib64/libimsmedia_jni.so+0x31b8)
    #2 0x7681c104d8 in art::JavaVMExt::LoadNativeLibrary(_JNIEnv*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, _jobject*, _jclass*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) (/apex/com.android.art/lib64/libart.so+0x5be4d8)
    #3 0x7678bf2128 in JVM_NativeLoad (/apex/com.android.art/lib64/libopenjdkjvm.so+0x8128)
    #4 0x6fba7a24  (/apex/com.android.art/javalib/arm64/boot.oat+0x80a24)

然后执行(asan_symbolize路径,android\external\compiler-rt\lib\asan\scripts)

asan_symbolize -s "$OUT/symbols"/ < ./external/compiler-rt/lib/asan/scripts/dumpinfo
#0 0x7332a21308 in _Z18load_ims_media_libPKc vendor/qcom/proprietary/commonsys/telephony-apps/ims/jni/media/ims_media_jni.cpp:477:56
   #1 0x7332a211b8 in _Z18load_ims_media_libPKc vendor/qcom/proprietary/commonsys/telephony-apps/ims/jni/media/ims_media_jni.cpp:0:0
   #2 0x73a24dc168 in _ZN3art9JavaVMExt17LoadNativeLibraryEP7_JNIEnvRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEP8_jobjectP7_jclassPS9_ art/runtime/jni/java_vm_ext.cc:1080:19
   #3 0x7399a1b16c in JVM_NativeLoad art/openjdkjvm/OpenjdkJvm.cc:333:24

5. FAQ

5.1 system 编译失败

由于当前为非动态分区,且system分区大小为1.5G,开启ASAN/HWASAN后,编译的system.img超过了1.5G,因此需要按照如下修改(后续改成动态分区则不需要修改了)

partion

vi device/jxx/shift/BoardConfig.mk
ifneq ($(strip $(BOARD_DYNAMIC_PARTITION_ENABLE)),true)
#BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
BOARD_VENDORIMAGE_PARTITION_SIZE := 1043333120 #1073741824
ifeq ($(strip $(WITH_GMS)),true)
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 3093299200 #3221225472
else
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 3093299200 #1610612736
endif
BOARD_PRODUCTIMAGE_PARTITION_SIZE := 838860800
ifeq ($(ENABLE_AB), true)
AB_OTA_PARTITIONS ?= system
endif
else

5.2 Not enough space to resize partition

烧录system时,提示无足够空间,因为当前ROM是4G,而system.img超过了1.5G,烧录system时,除了system.img,还剩余空间少于1.5G,因此失败,此时需要将system和vendor打包为super.img烧录

  • super打包命令
lpmake --metadata-size 65536 --super-name super --metadata-slots 3 --virtual-ab --device super:4294967296 \
       --group qti_dynamic_partitions_a:4290772992  --group qti_dynamic_partitions_b:4290772992 \
       --partition system_a:readonly:$(get_build_var BOARD_SYSTEMIMAGE_PARTITION_SIZE):qti_dynamic_partitions_a --image system_a=$OUT/system.img \
       --partition system_b:readonly:0:qti_dynamic_partitions_b \
       --partition system_ext_a:readonly:0:qti_dynamic_partitions_a \
       --partition system_ext_b:readonly:0:qti_dynamic_partitions_b \
       --partition product_a:readonly:0:qti_dynamic_partitions_a \
       --partition product_b:readonly:0:qti_dynamic_partitions_b \
       --partition vendor_a:readonly:$(get_build_var BOARD_VENDORIMAGE_PARTITION_SIZE):qti_dynamic_partitions_a --image vendor_a=$OUT/vendor.img \
       --partition vendor_b:readonly:0:qti_dynamic_partitions_b \
       --sparse --output $OUT/super.img
  • super烧录命令
fastboot flash super super.img

5.3 userdata 烧录

由于文件系统的不同,烧录userdata会导致系统无法启动,因此在烧录特殊版本的ASAN时,不烧录userdata.img,待system、vendor烧录启动后,push $OUT/data/asan到板卡的data目录下即可文章来源地址https://www.toymoban.com/news/detail-618276.html

到了这里,关于ASan和HWAsan在Android中使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 内存检测工具——ASan(AddressSanitizer)的介绍和使用

    ASan全称AddressSanitizer,是一种内存错误检测工具,目的是帮助开发者检测和调试内存相关的问题,如使用未分配的内存、使用已释放的内存、堆内存溢出等。ASan是由Google开发的,广泛用于C、C++等语言的代码中。 ASan的工作原理是在编译时将额外的代码插入到目标程序中,对内

    2024年03月20日
    浏览(41)
  • 云计算基础-存储虚拟化(深信服aSAN分布式存储)

    分布式存储是利用虚拟化技术 “池化”集群存储卷内通用X86服务器中的本地硬盘,实现服务器存储资源的统一整合、管理及调度,最终向上层提供NFS、ISCSI存储接口,供虚拟机根据自身的存储需求自由分配使用资源池中的存储空间。 每秒钟的IOPS数,该指标主要用于评价小块

    2024年02月19日
    浏览(40)
  • 【Android】使用Android Studio打包APK文件

    打包APK之前,首先需要新建项目,有基础的可以跳过。 无基础的可以参考:使用Android Studio运行Hello World项目 1.找到Build - Generate Signed Bundle or APK - 勾选APK 2.首次需要创建证书,后续可以使用已创建好的证书 3.填写证书信息 选择密钥库存放路径,并填写密码 填写密钥名称、密

    2024年02月19日
    浏览(56)
  • 【Android】最新版Android13使用Notification,Notification的基本使用和进阶使用

    1.1 注册一个渠道 在Android13,版本通知的使用发生了新的变化。 1.1.1 NotificationManager原生类 首先我们需要创建一个 NotificationManager 用于管理通知。 NotificationManager 仅支持在 API 等级 11(Android 3.0)及以上的设备上使用 ,因此在较旧的 Android 版本上无法使用较新的通知功能。 `

    2024年01月17日
    浏览(42)
  • Android GreenDao 使用全面讲解,Android组件化入门

    5. 在多个线程中使用QueryBuilder 如果在多个线程中使用查询,则必须调用 forCurrentThread ()以获取当前线程的Query实例。Query的对象实例绑定到构建查询的拥有线程。 这使您可以安全地在Query对象上设置参数,而其他线程不会干扰。如果其他线程尝试在查询上设置参数或执行绑

    2024年04月27日
    浏览(52)
  • Android查看签名信息系列 · 使用Android Studio获取签名

    前言 Android查看签名信息系列 之使用Android Studio获取签名,通过Android Studio自带的gradle来获取签名信息。 优点:此法可查看 MD5、SHA1 等信息。 缺点:升级某个Studio版本后,没有签名任务了,特别不方便。 实现方法 一、使用 Android Studio 创建gradle获取签名信息。 1、使用 Androi

    2024年02月07日
    浏览(51)
  • 【Android笔记97】Android之RecyclerView使用GridLayoutManager网格布局

    这篇文章,主要介绍Android之RecyclerView使用GridLayoutManager网格布局。 目录 一、GridLayoutManager网格布局 1.1、功能效果 1.2、案例代码 (1)创建网格布局

    2024年02月15日
    浏览(40)
  • Android Architecture Components ——LiveData使用,android热修复视频

    小结:getApplication()即是全局的上下文 Activity中进行数据监听 import android.arch.lifecycle.MutableLiveData; import android.arch.lifecycle.Observer; import android.arch.lifecycle.ViewModelProviders; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log;

    2024年04月17日
    浏览(45)
  • Android串口开发之使用JNI实现ANDROID和串口通信

    导语:Android串口通信在物联网、智能家居等领域具有广泛的应用。本文将详细介绍如何使用JNI技术实现Android设备与串口的通信,包括串口的打开、设置参数和读写数据等过程。 在开始介绍Android串口开发之前,我们需要了解以下几个概念: JNI:JNI(Java Native Interface)是一种

    2024年02月07日
    浏览(48)
  • 【Android笔记108】Android之翻转视图组件ViewFlipper的使用

    这篇文章,主要介绍Android之翻转视图组件ViewFlipper的使用。 目录 一、翻转视图ViewFlipper 1.1、什么是ViewFlipper 1.2、运行效果 (1)不带动画的效果

    2024年02月08日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包