├── .gitignore ├── .gitmodules ├── Android.bp ├── CMakeLists.txt ├── LICENSE ├── README.md ├── Snipaste_2022-10-16_21-55-55.png ├── bin └── unwinddaemon ├── build.sh ├── hook_open_with_stack.py ├── init-submodules.sh ├── lib.cpp ├── main.cpp └── shim_files ├── liblog └── include │ ├── android │ └── log.h │ ├── log │ ├── event_tag_map.h │ ├── log.h │ ├── log_event_list.h │ ├── log_id.h │ ├── log_main.h │ ├── log_properties.h │ ├── log_radio.h │ ├── log_read.h │ ├── log_safetynet.h │ ├── log_system.h │ ├── log_time.h │ └── logprint.h │ └── private │ └── android_logger.h └── libunwindstack ├── Demangle.cpp └── ThreadUnwinder.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | build -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "external/art"] 2 | path = external/art 3 | url = https://android.googlesource.com/platform/art 4 | branch = android14-release 5 | [submodule "external/libbase"] 6 | path = external/libbase 7 | url = https://android.googlesource.com/platform/system/libbase 8 | branch = android14-release 9 | [submodule "external/logging"] 10 | path = external/logging 11 | url = https://android.googlesource.com/platform/system/logging 12 | branch = android14-release 13 | [submodule "external/libnativehelper"] 14 | path = external/libnativehelper 15 | url = https://android.googlesource.com/platform/libnativehelper 16 | branch = android14-release 17 | [submodule "external/libprocinfo"] 18 | path = external/libprocinfo 19 | url = https://android.googlesource.com/platform/system/libprocinfo 20 | branch = android14-release 21 | [submodule "external/unwinding"] 22 | path = external/unwinding 23 | url = https://android.googlesource.com/platform/system/unwinding 24 | branch = android14-release 25 | [submodule "external/lzma"] 26 | path = external/lzma 27 | url = https://android.googlesource.com/platform/external/lzma 28 | branch = android14-release 29 | [submodule "external/bionic"] 30 | path = external/bionic 31 | url = https://android.googlesource.com/platform/bionic 32 | branch = android14-release 33 | -------------------------------------------------------------------------------- /Android.bp: -------------------------------------------------------------------------------- 1 | cc_binary { 2 | name: "unwinddaemon", 3 | srcs: ["main.cpp"], 4 | 5 | cflags: [ 6 | "-Wall", 7 | "-Werror", 8 | "-Wextra", 9 | ], 10 | 11 | shared_libs: [ 12 | "libbase", 13 | "liblog", 14 | "libunwindstack", 15 | ], 16 | } 17 | 18 | cc_library_shared { 19 | name: "libstackplz", 20 | srcs: ["lib.cpp"], 21 | 22 | cflags: [ 23 | "-g", 24 | "-Wall", 25 | "-Werror", 26 | "-Wextra", 27 | ], 28 | 29 | shared_libs: [ 30 | "liblog", 31 | "libbase", 32 | ], 33 | 34 | static_libs: [ 35 | "libunwindstack", 36 | "libdexfile_support", 37 | "liblzma", 38 | "libasync_safe", 39 | ], 40 | 41 | min_sdk_version: "29", 42 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.22.1) 2 | project("stackplz") 3 | 4 | enable_language(C CXX ASM) 5 | 6 | set(CMAKE_CXX_STANDARD 20) 7 | set(CMAKE_C_STANDARD 11) 8 | 9 | set(C_FLAGS "-Wall -Wextra -fvisibility=hidden -fvisibility-inlines-hidden -fno-exceptions -fno-rtti -flto=thin") 10 | set(LINKER_FLAGS "-fuse-ld=lld -flto=thin -ffixed-x18 -Wl,--hash-style=both -Wl,--unresolved-symbols=ignore-all") 11 | 12 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -fvisibility=hidden") 13 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -fvisibility=hidden") 14 | 15 | set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,text,-z,defs,-z,now,-z,relro") 16 | 17 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer") 18 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -Werror=non-virtual-dtor -Werror=delete-non-virtual-dtor") 19 | 20 | set(SHIM_SRC "shim_files") 21 | set(EXTERNAL_SRC "external") 22 | set(UNWINDING_SRC "external/unwinding") 23 | set(DEXFILE_SRC "external/art/libdexfile") 24 | 25 | if (DEFINED ANDROID_ABI) 26 | if (ANDROID_ABI STREQUAL "x86") 27 | set(UNWINDSTACK_ARCH "x86") 28 | elseif (ANDROID_ABI STREQUAL "x86_64") 29 | set(UNWINDSTACK_ARCH "x86_64") 30 | elseif (ANDROID_ABI STREQUAL "armeabi-v7a") 31 | set(UNWINDSTACK_ARCH "arm") 32 | elseif (ANDROID_ABI STREQUAL "arm64-v8a") 33 | set(UNWINDSTACK_ARCH "arm64") 34 | else () 35 | message(FATAL_ERROR "Unsupported ANDROID_ABI: ${ANDROID_ABI}") 36 | endif () 37 | else () 38 | if (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "i686") 39 | set(UNWINDSTACK_ARCH "x86") 40 | elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64") 41 | set(UNWINDSTACK_ARCH "x86_64") 42 | elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7-a") 43 | set(UNWINDSTACK_ARCH "arm") 44 | elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "armv8-a") 45 | set(UNWINDSTACK_ARCH "arm64") 46 | else () 47 | message(FATAL_ERROR "Unsupported CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") 48 | endif () 49 | endif () 50 | 51 | # architecture-specific sources 52 | if (UNWINDSTACK_ARCH STREQUAL "x86") 53 | set(UNWINDSTACK_ARCH_SRC "${UNWINDING_SRC}/libunwindstack/AsmGetRegsX86.S") 54 | elseif (UNWINDSTACK_ARCH STREQUAL "x86_64") 55 | set(UNWINDSTACK_ARCH_SRC "${UNWINDING_SRC}/libunwindstack/AsmGetRegsX86_64.S") 56 | else () 57 | set(UNWINDSTACK_ARCH_SRC "") 58 | endif () 59 | 60 | if (UNWINDSTACK_ARCH STREQUAL "x86") 61 | list(APPEND ART_COMPILE_C_FLAGS "-DART_ENABLE_CODEGEN_x86") 62 | elseif (UNWINDSTACK_ARCH STREQUAL "x86_64") 63 | list(APPEND ART_COMPILE_C_FLAGS "-DART_ENABLE_CODEGEN_x86_64" "-DART_ENABLE_CODEGEN_x86") 64 | elseif (UNWINDSTACK_ARCH STREQUAL "arm") 65 | list(APPEND ART_COMPILE_C_FLAGS "-DART_ENABLE_CODEGEN_arm") 66 | elseif (UNWINDSTACK_ARCH STREQUAL "arm64") 67 | list(APPEND ART_COMPILE_C_FLAGS "-DART_ENABLE_CODEGEN_arm64" "-DART_ENABLE_CODEGEN_arm") 68 | endif () 69 | 70 | add_library(base STATIC 71 | "${EXTERNAL_SRC}/libbase/chrono_utils.cpp" 72 | "${EXTERNAL_SRC}/libbase/file.cpp" 73 | "${EXTERNAL_SRC}/libbase/hex.cpp" 74 | "${EXTERNAL_SRC}/libbase/mapped_file.cpp" 75 | "${EXTERNAL_SRC}/libbase/parsebool.cpp" 76 | "${EXTERNAL_SRC}/libbase/parsenetaddress.cpp" 77 | "${EXTERNAL_SRC}/libbase/logging.cpp" 78 | "${EXTERNAL_SRC}/libbase/posix_strerror_r.cpp" 79 | "${EXTERNAL_SRC}/libbase/process.cpp" 80 | "${EXTERNAL_SRC}/libbase/stringprintf.cpp" 81 | "${EXTERNAL_SRC}/libbase/strings.cpp" 82 | "${EXTERNAL_SRC}/libbase/threads.cpp" 83 | ) 84 | target_include_directories(base PUBLIC "${EXTERNAL_SRC}/libbase/include" "${SHIM_SRC}/liblog/include") 85 | target_compile_options(base PRIVATE -Wno-c99-designator) 86 | 87 | add_library(procinfo STATIC "${EXTERNAL_SRC}/libprocinfo/process.cpp") 88 | target_include_directories(procinfo PUBLIC "${EXTERNAL_SRC}/libbase/include" "${EXTERNAL_SRC}/libprocinfo/include") 89 | 90 | add_library(lzma STATIC 91 | "${EXTERNAL_SRC}/lzma/C/7zAlloc.c" 92 | "${EXTERNAL_SRC}/lzma/C/7zArcIn.c" 93 | "${EXTERNAL_SRC}/lzma/C/7zBuf2.c" 94 | "${EXTERNAL_SRC}/lzma/C/7zBuf.c" 95 | "${EXTERNAL_SRC}/lzma/C/7zCrc.c" 96 | "${EXTERNAL_SRC}/lzma/C/7zCrcOpt.c" 97 | "${EXTERNAL_SRC}/lzma/C/7zDec.c" 98 | "${EXTERNAL_SRC}/lzma/C/7zFile.c" 99 | "${EXTERNAL_SRC}/lzma/C/7zStream.c" 100 | "${EXTERNAL_SRC}/lzma/C/Aes.c" 101 | "${EXTERNAL_SRC}/lzma/C/AesOpt.c" 102 | "${EXTERNAL_SRC}/lzma/C/Alloc.c" 103 | "${EXTERNAL_SRC}/lzma/C/Bcj2.c" 104 | "${EXTERNAL_SRC}/lzma/C/Bra86.c" 105 | "${EXTERNAL_SRC}/lzma/C/Bra.c" 106 | "${EXTERNAL_SRC}/lzma/C/BraIA64.c" 107 | "${EXTERNAL_SRC}/lzma/C/CpuArch.c" 108 | "${EXTERNAL_SRC}/lzma/C/Delta.c" 109 | "${EXTERNAL_SRC}/lzma/C/LzFind.c" 110 | "${EXTERNAL_SRC}/lzma/C/Lzma2Dec.c" 111 | "${EXTERNAL_SRC}/lzma/C/Lzma2Enc.c" 112 | "${EXTERNAL_SRC}/lzma/C/Lzma86Dec.c" 113 | "${EXTERNAL_SRC}/lzma/C/Lzma86Enc.c" 114 | "${EXTERNAL_SRC}/lzma/C/LzmaDec.c" 115 | "${EXTERNAL_SRC}/lzma/C/LzmaEnc.c" 116 | "${EXTERNAL_SRC}/lzma/C/LzmaLib.c" 117 | "${EXTERNAL_SRC}/lzma/C/Ppmd7.c" 118 | "${EXTERNAL_SRC}/lzma/C/Ppmd7Dec.c" 119 | "${EXTERNAL_SRC}/lzma/C/Ppmd7Enc.c" 120 | "${EXTERNAL_SRC}/lzma/C/Sha256.c" 121 | "${EXTERNAL_SRC}/lzma/C/Sort.c" 122 | "${EXTERNAL_SRC}/lzma/C/Xz.c" 123 | "${EXTERNAL_SRC}/lzma/C/XzCrc64.c" 124 | "${EXTERNAL_SRC}/lzma/C/XzCrc64Opt.c" 125 | "${EXTERNAL_SRC}/lzma/C/XzDec.c" 126 | "${EXTERNAL_SRC}/lzma/C/XzEnc.c" 127 | "${EXTERNAL_SRC}/lzma/C/XzIn.c" 128 | ) 129 | target_include_directories(lzma PUBLIC "${EXTERNAL_SRC}/lzma/C") 130 | target_compile_options(lzma PRIVATE -fPIC "-D_7ZIP_ST") 131 | 132 | add_library(dexfile_support STATIC 133 | "${DEXFILE_SRC}/external/dex_file_supp.cc" 134 | ) 135 | target_include_directories(dexfile_support 136 | PUBLIC "${DEXFILE_SRC}/external/include" 137 | PUBLIC "${SHIM_SRC}/liblog/include" 138 | ) 139 | 140 | add_library(unwindstack STATIC 141 | "${UNWINDING_SRC}/libunwindstack/AndroidUnwinder.cpp" 142 | "${UNWINDING_SRC}/libunwindstack/ArmExidx.cpp" 143 | # "${UNWINDING_SRC}/libunwindstack/Demangle.cpp" 144 | "${SHIM_SRC}/libunwindstack/Demangle.cpp" 145 | "${UNWINDING_SRC}/libunwindstack/DexFiles.cpp" 146 | "${UNWINDING_SRC}/libunwindstack/DwarfCfa.cpp" 147 | "${UNWINDING_SRC}/libunwindstack/DwarfEhFrameWithHdr.cpp" 148 | "${UNWINDING_SRC}/libunwindstack/DwarfMemory.cpp" 149 | "${UNWINDING_SRC}/libunwindstack/DwarfOp.cpp" 150 | "${UNWINDING_SRC}/libunwindstack/DwarfSection.cpp" 151 | "${UNWINDING_SRC}/libunwindstack/Elf.cpp" 152 | "${UNWINDING_SRC}/libunwindstack/ElfInterface.cpp" 153 | "${UNWINDING_SRC}/libunwindstack/ElfInterfaceArm.cpp" 154 | "${UNWINDING_SRC}/libunwindstack/Global.cpp" 155 | "${UNWINDING_SRC}/libunwindstack/JitDebug.cpp" 156 | "${UNWINDING_SRC}/libunwindstack/MapInfo.cpp" 157 | "${UNWINDING_SRC}/libunwindstack/Maps.cpp" 158 | "${UNWINDING_SRC}/libunwindstack/Memory.cpp" 159 | "${UNWINDING_SRC}/libunwindstack/MemoryMte.cpp" 160 | "${UNWINDING_SRC}/libunwindstack/MemoryXz.cpp" 161 | "${UNWINDING_SRC}/libunwindstack/Regs.cpp" 162 | "${UNWINDING_SRC}/libunwindstack/RegsArm.cpp" 163 | "${UNWINDING_SRC}/libunwindstack/RegsArm64.cpp" 164 | "${UNWINDING_SRC}/libunwindstack/RegsX86.cpp" 165 | "${UNWINDING_SRC}/libunwindstack/RegsX86_64.cpp" 166 | "${UNWINDING_SRC}/libunwindstack/RegsRiscv64.cpp" 167 | "${UNWINDING_SRC}/libunwindstack/RegsMips.cpp" 168 | "${UNWINDING_SRC}/libunwindstack/RegsMips64.cpp" 169 | "${UNWINDING_SRC}/libunwindstack/Symbols.cpp" 170 | "${UNWINDING_SRC}/libunwindstack/ThreadEntry.cpp" 171 | # "${UNWINDING_SRC}/libunwindstack/ThreadUnwinder.cpp" 172 | "${SHIM_SRC}/libunwindstack/ThreadUnwinder.cpp" 173 | "${UNWINDING_SRC}/libunwindstack/Unwinder.cpp" 174 | 175 | "${UNWINDING_SRC}/libunwindstack/DexFile.cpp" 176 | "${UNWINDING_SRC}/libunwindstack/LogAndroid.cpp" 177 | 178 | "${UNWINDSTACK_ARCH_SRC}" 179 | ) 180 | 181 | target_include_directories(unwindstack 182 | PUBLIC "${UNWINDING_SRC}/libunwindstack" 183 | PUBLIC "${UNWINDING_SRC}/libunwindstack/include" 184 | PUBLIC "${EXTERNAL_SRC}/libbase/include" 185 | PUBLIC "${EXTERNAL_SRC}/bionic/libc/platform" 186 | PUBLIC "${EXTERNAL_SRC}/bionic/libc/async_safe/include" 187 | PUBLIC "${EXTERNAL_SRC}/libprocinfo/include" 188 | PUBLIC "${EXTERNAL_SRC}/lzma/C" 189 | PUBLIC "${EXTERNAL_SRC}/art/libdexfile/external/include" 190 | PUBLIC "${SHIM_SRC}/liblog/include" 191 | ) 192 | target_compile_options(unwindstack PRIVATE -Wno-c99-designator) 193 | target_compile_definitions(unwindstack PRIVATE DEXFILE_SUPPORT=1) 194 | 195 | # check are we top-level project 196 | if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) 197 | 198 | add_library(${PROJECT_NAME} SHARED lib.cpp) 199 | 200 | SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-Wl,-s") 201 | 202 | target_include_directories(${PROJECT_NAME} PUBLIC ${EXTERNAL_SRC}/libbase/include) 203 | target_include_directories(${PROJECT_NAME} PUBLIC ${EXTERNAL_SRC}/bionic/libc/kernel/uapi) 204 | target_include_directories(${PROJECT_NAME} PUBLIC ${EXTERNAL_SRC}/unwinding/libunwindstack/include) 205 | target_compile_definitions(${PROJECT_NAME} PRIVATE DEXFILE_SUPPORT=1) 206 | 207 | target_link_libraries(${PROJECT_NAME} base procinfo lzma dexfile_support unwindstack log) 208 | 209 | endif () -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 SeeFlowerX 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # unwinddaemon 2 | 3 | ## CMAKE + NDK编译步骤 4 | 5 | 拉取本项目,然后执行下面的命令 6 | 7 | ```bash 8 | git submodule init 9 | git submodule update --remote 10 | ``` 11 | 12 | 如果是想手工配置,则执行下面的脚本 13 | 14 | ```bash 15 | ./init-submodules.sh 16 | ``` 17 | 18 | 编译执行下面的脚本即可,产物位于`build`文件夹,注意只有单个so,部分依赖为静态编译,具体请阅读`CMakeLists.txt` 19 | 20 | 记得先修改`ANDROID_NDK`路径,如果要编译Android 10的版本,请将`ANDROID_PLATFORM`修改为`android-29` 21 | 22 | ```bash 23 | ./build.sh 24 | ``` 25 | 26 | 关于`shim_files`的构成: 27 | 28 | - liblog 29 | - 这个下面的头文件其实就是从`system/logging`拿过来的 30 | - 为了能编译出在Android10上使用的库,给`include/android/log.h`添加了一些Android10上没有的函数声明 31 | - 测试暂时没有出现崩溃迹象 32 | 33 | - libunwindstack 34 | - 项目所需要的源码是从`android14-release`分支拉取的,`Demangle.cpp`有rust相关的内容,这里去掉了 35 | - `ThreadUnwinder.cpp`中有关`struct sigaction`的初始化会被编译器报警告,这里改了一下 36 | 37 | **本方案编译实现主要参考了以下两个项目,感谢:** 38 | 39 | - https://github.com/cinit/libunwindstack 40 | - https://github.com/Mufanc/libunwindstack-standalone 41 | 42 | ## 基于AOSP的编译步骤 43 | 44 | - 同步AOSP 45 | - 在AOSP源码文件夹下创建`system/extras/unwinddaemon`文件夹 46 | - 将本项目的`Android.bp`和`main.cpp`放入上一步创建的文件夹 47 | - 在AOSP源码文件夹下打开终端,执行下面的命令进行编译 48 | ```bash 49 | . build/envsetup.sh 50 | lunch aosp_arm64-eng 51 | mmma system/extras/unwinddaemon 52 | ``` 53 | - 编译成功后,产物在`out/target/product/generic_arm64/system/bin/unwinddaemon` 54 | 55 | ## 使用 56 | 57 | 将`out/target/product/generic_arm64/system/bin/unwinddaemon`推送到手机的`/data/local/tmp`,授予可执行权限 58 | 59 | 然后执行`/data/local/tmp/unwinddaemon`即可 60 | 61 | `hook_open_with_stack.py`是配合bcc修改使用的demo 62 | 63 | `bin/unwinddaemon`是预编译好的,但不一定兼容 64 | 65 | bcc修改参见 66 | 67 | - https://github.com/SeeFlowerX/unwindbcc/commit/f6548633e1d8afd527637f0da69959046986a25c 68 | 69 | 原理,代码修改等,请查阅[eBPF on Android之实现基于dwarf的用户态栈回溯](https://blog.seeflower.dev/archives/175/) 70 | 71 | ## 效果示意图 72 | 73 | ![](./Snipaste_2022-10-16_21-55-55.png) 74 | 75 | --- 76 | 77 | ## 共享库版本 78 | 79 | 编译`lib.cpp`得到的产物如下,在[SeeFlowerX/stackplz](https://github.com/SeeFlowerX/stackplz)中使用 80 | 81 | ```bash 82 | ld-android.so 83 | libbase.so 84 | libc++.so 85 | libdl.so 86 | liblog.so 87 | liblzma.so 88 | libm.so 89 | libstackplz.so 90 | libunwindstack.so 91 | ``` -------------------------------------------------------------------------------- /Snipaste_2022-10-16_21-55-55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeeFlowerX/unwinddaemon/3a4a5e7dcf34b4058af42843a1c5c03a09e1ad81/Snipaste_2022-10-16_21-55-55.png -------------------------------------------------------------------------------- /bin/unwinddaemon: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SeeFlowerX/unwinddaemon/3a4a5e7dcf34b4058af42843a1c5c03a09e1ad81/bin/unwinddaemon -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | export ANDROID_NDK=/home/kali/Desktop/android-ndk-r25b 4 | 5 | rm -r build 6 | mkdir build && cd build 7 | 8 | cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \ 9 | -DANDROID=1 \ 10 | -DANDROID_ABI="arm64-v8a" \ 11 | -DANDROID_NDK=$ANDROID_NDK \ 12 | -DANDROID_PLATFORM=android-30 \ 13 | .. 14 | 15 | make 16 | 17 | cd .. 18 | -------------------------------------------------------------------------------- /hook_open_with_stack.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import logging 3 | from pathlib import Path 4 | from datetime import datetime 5 | 6 | from bcc import BPF 7 | 8 | GLOBAL_LOGGERS = {} 9 | logger = None # type: logging.Logger 10 | 11 | def setup_logger(log_tag: str, log_path: Path, first_call: bool = False) -> logging.Logger: 12 | ''' 13 | 输出的信息太多 Terminal可能不全 记录到日志文件 14 | ''' 15 | if log_path.parent.exists() is False: 16 | log_path.parent.mkdir() 17 | logger = GLOBAL_LOGGERS.get(log_tag) 18 | if logger: 19 | return logger 20 | 21 | logger = logging.getLogger(log_tag) 22 | GLOBAL_LOGGERS[log_tag] = logger 23 | 24 | # 避免重新载入脚本时重复输出 25 | if first_call and logger.hasHandlers(): 26 | logger.handlers.clear() 27 | 28 | # 设置所有 handler 的日志等级 29 | logger.setLevel(logging.DEBUG) 30 | 31 | # 添加终端 handler 只打印原始信息 32 | formatter = logging.Formatter('%(message)s') 33 | ch = logging.StreamHandler(sys.stdout) 34 | ch.setLevel(logging.DEBUG) 35 | ch.setFormatter(formatter) 36 | logger.addHandler(ch) 37 | 38 | # 添加文件 handler 记录详细时间和内容 39 | formatter = logging.Formatter('%(asctime)s.%(msecs)03d %(levelname)s: %(message)s', datefmt='%H:%M:%S') 40 | fh = logging.FileHandler(log_path.as_posix(), encoding='utf-8', delay=True) 41 | fh.setLevel(logging.DEBUG) 42 | fh.setFormatter(formatter) 43 | logger.addHandler(fh) 44 | 45 | return logger 46 | 47 | 48 | BPF_CODE_include = """ 49 | #include 50 | """ 51 | 52 | BPF_CODE_open = """ 53 | struct probe_open_data_t { 54 | u32 pid; 55 | u32 tid; 56 | u32 uid; 57 | char pathname[256]; 58 | int flags; 59 | }; 60 | 61 | BPF_PERCPU_ARRAY(open_data, struct probe_open_data_t, 1); 62 | BPF_PERF_OUTPUT(perf_open); 63 | 64 | // int open(const char* pathname, int flags, ...) 65 | 66 | int probe_hook_open_enter(struct pt_regs *ctx) { 67 | u64 pid_tgid = bpf_get_current_pid_tgid(); 68 | u32 pid = pid_tgid >> 32; 69 | u32 tid = (u32)pid_tgid; 70 | u32 uid = bpf_get_current_uid_gid(); 71 | 72 | PID_FILTER 73 | TID_FILTER 74 | UID_FILTER 75 | 76 | u32 zero = 0; 77 | struct probe_open_data_t *data = open_data.lookup(&zero); 78 | if (!data) 79 | return 0; 80 | 81 | data->pid = pid; 82 | data->tid = tid; 83 | data->uid = uid; 84 | data->flags = PT_REGS_PARM2(ctx); 85 | 86 | int ret = bpf_probe_read_user(data->pathname, sizeof(data->pathname), (void *)PT_REGS_PARM1(ctx)); 87 | perf_open.perf_submit(ctx, data, sizeof(struct probe_open_data_t)); 88 | return 0; 89 | } 90 | """ 91 | 92 | class BPFHooker: 93 | 94 | def __init__(self, library: str, uid: int, pid: int = -1, tid: int = -1) -> None: 95 | # 可以是库名 比如 libssl.so 取 ssl 96 | # 可以是是目标ELF程序的完整路径 比如 /apex/com.android.conscrypt/lib64/libssl.so 97 | # 如果要写路径 那么内存里面是什么就是什么 不要使用软链接的路径 98 | self.uid = uid 99 | self.pid = pid 100 | self.tid = tid 101 | self.library = library 102 | self.bpf_module = None # type: BPF 103 | 104 | def hook(self): 105 | text = BPF_CODE_include 106 | text += BPF_CODE_open 107 | if self.pid > 0: 108 | text = text.replace('PID_FILTER', f'if (pid != {self.pid}) {{ return 0; }}') 109 | else: 110 | text = text.replace('PID_FILTER', '') 111 | if self.tid > 0: 112 | text = text.replace('TID_FILTER', f'if (tid != {self.tid}) {{ return 0; }}') 113 | else: 114 | text = text.replace('TID_FILTER', '') 115 | if self.uid > 0: 116 | text = text.replace('UID_FILTER', f'if (uid != {self.uid}) {{ return 0; }}') 117 | else: 118 | text = text.replace('UID_FILTER', '') 119 | self.bpf_module = BPF(text=text) 120 | self.bpf_module.attach_uprobe(name=self.library, sym='open', fn_name='probe_hook_open_enter', pid=self.pid) 121 | logger.info('attach end') 122 | 123 | def print_event_perf_open(self, ctx, data, size): 124 | event = self.bpf_module['perf_open'].event(data) 125 | logger.info(f'[open] {event.pathname.decode("utf-8")}') 126 | 127 | def show(self): 128 | self.bpf_module["perf_open"].open_perf_buffer(self.print_event_perf_open, unwind_call_stack=1) 129 | while True: 130 | try: 131 | self.bpf_module.perf_buffer_poll() 132 | except KeyboardInterrupt: 133 | exit() 134 | 135 | def main(): 136 | global logger 137 | log_tag = 'open' 138 | log_time = datetime.now().strftime('%Y%m%d_%H%M%S') 139 | log_path = Path(__file__).parent / f'logs/{log_tag}_{log_time}.log' 140 | logger = setup_logger(log_tag, log_path, first_call=True) 141 | uid = 10235 142 | library = "/apex/com.android.runtime/lib64/bionic/libc.so" 143 | bpf_hooker = BPFHooker(library, uid) 144 | bpf_hooker.hook() 145 | bpf_hooker.show() 146 | 147 | 148 | if __name__ == '__main__': 149 | main() -------------------------------------------------------------------------------- /init-submodules.sh: -------------------------------------------------------------------------------- 1 | BRANCH=android14-release 2 | 3 | git submodule add -b "$BRANCH" https://android.googlesource.com/platform/art external/art 4 | git submodule add -b "$BRANCH" https://android.googlesource.com/platform/system/libbase external/libbase 5 | # git submodule add -b "$BRANCH" https://android.googlesource.com/platform/system/logging external/logging 6 | git submodule add -b "$BRANCH" https://android.googlesource.com/platform/libnativehelper external/libnativehelper 7 | git submodule add -b "$BRANCH" https://android.googlesource.com/platform/system/libprocinfo external/libprocinfo 8 | git submodule add -b "$BRANCH" https://android.googlesource.com/platform/system/unwinding external/unwinding 9 | git submodule add -b "$BRANCH" https://android.googlesource.com/platform/external/lzma external/lzma 10 | git submodule add -b "$BRANCH" https://android.googlesource.com/platform/bionic external/bionic -------------------------------------------------------------------------------- /lib.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | // #include 11 | 12 | #if defined(USE_BIONIC_UAPI_HEADERS) 13 | #include 14 | #undef PERF_REG_EXTENDED_MASK 15 | #include 16 | #undef PERF_REG_EXTENDED_MASK 17 | #include 18 | #undef PERF_REG_EXTENDED_MASK 19 | #define perf_event_arm_regs perf_event_arm64_regs 20 | #include 21 | #undef PERF_REG_EXTENDED_MASK 22 | #else 23 | #include 24 | #undef PERF_REG_EXTENDED_MASK 25 | #include 26 | #undef PERF_REG_EXTENDED_MASK 27 | #include 28 | #undef PERF_REG_EXTENDED_MASK 29 | #define perf_event_arm_regs perf_event_arm64_regs 30 | #include 31 | #undef PERF_REG_EXTENDED_MASK 32 | #endif 33 | 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | 54 | // Use the demangler from libc++. 55 | extern "C" char* __cxa_demangle(const char*, char*, size_t*, int* status); 56 | 57 | namespace unwinddaemon { 58 | 59 | class MyAndroidRemoteUnwinder : public unwindstack::AndroidRemoteUnwinder { 60 | public: 61 | MyAndroidRemoteUnwinder(pid_t pid, bool show_pc) 62 | : unwindstack::AndroidRemoteUnwinder(pid), show_pc(show_pc) {} 63 | 64 | void SetArch(unwindstack::ArchEnum arch) { arch_ = arch; }; 65 | void SetMaxFrames(size_t max_frames) { max_frames_ = max_frames; }; 66 | void SetDisplayBuildID(bool display_build_id) { display_build_id_ = display_build_id; } 67 | std::string FormatFrame(const unwindstack::FrameData& frame) const; 68 | 69 | virtual ~MyAndroidRemoteUnwinder() = default; 70 | 71 | protected: 72 | bool InternalInitialize(unwindstack::ErrorData& error) override; 73 | 74 | bool show_pc = false; 75 | bool display_build_id_ = false; 76 | 77 | }; 78 | 79 | bool MyAndroidRemoteUnwinder::InternalInitialize(unwindstack::ErrorData& error) { 80 | // 初始化的时候已经处理了 arch_ 81 | 82 | maps_.reset(new unwindstack::RemoteMaps(pid_)); 83 | if (!maps_->Parse()) { 84 | error.code = unwindstack::ERROR_MAPS_PARSE; 85 | return false; 86 | } 87 | 88 | if (process_memory_ == nullptr) { 89 | process_memory_ = unwindstack::Memory::CreateProcessMemoryCached(pid_); 90 | } 91 | 92 | return true; 93 | } 94 | 95 | 96 | std::string MyAndroidRemoteUnwinder::FormatFrame(const unwindstack::FrameData& frame) const { 97 | 98 | std::string data; 99 | if (show_pc) { 100 | if (ArchIs32Bit(arch_)) { 101 | data += android::base::StringPrintf(" #%02zu pc %08" PRIx64 " %08" PRIx64, frame.num, frame.pc, frame.rel_pc); 102 | } else { 103 | data += android::base::StringPrintf(" #%02zu pc %016" PRIx64 " %016" PRIx64, frame.num, frame.pc, frame.rel_pc); 104 | } 105 | } else { 106 | if (ArchIs32Bit(arch_)) { 107 | data += android::base::StringPrintf(" #%02zu pc %08" PRIx64, frame.num, frame.rel_pc); 108 | } else { 109 | data += android::base::StringPrintf(" #%02zu pc %016" PRIx64, frame.num, frame.rel_pc); 110 | } 111 | } 112 | 113 | auto map_info = frame.map_info; 114 | if (map_info == nullptr) { 115 | // No valid map associated with this frame. 116 | data += " "; 117 | } else if (!map_info->name().empty()) { 118 | data += " "; 119 | data += map_info->GetFullName(); 120 | } else { 121 | data += android::base::StringPrintf(" ", map_info->start()); 122 | } 123 | 124 | if (map_info != nullptr && map_info->elf_start_offset() != 0) { 125 | data += android::base::StringPrintf(" (offset 0x%" PRIx64 ")", map_info->elf_start_offset()); 126 | } 127 | 128 | if (!frame.function_name.empty()) { 129 | char* demangled_name = __cxa_demangle(frame.function_name.c_str(), nullptr, nullptr, nullptr); 130 | if (demangled_name == nullptr) { 131 | data += " ("; 132 | data += frame.function_name; 133 | } else { 134 | data += " ("; 135 | data += demangled_name; 136 | free(demangled_name); 137 | } 138 | if (frame.function_offset != 0) { 139 | data += android::base::StringPrintf("+%" PRId64, frame.function_offset); 140 | } 141 | data += ')'; 142 | } 143 | 144 | if (map_info != nullptr && display_build_id_) { 145 | std::string build_id = map_info->GetPrintableBuildID(); 146 | if (!build_id.empty()) { 147 | data += " (BuildId: " + build_id + ')'; 148 | } 149 | } 150 | return data; 151 | } 152 | 153 | 154 | class UnwinderWithPC : public unwindstack::Unwinder { 155 | public: 156 | UnwinderWithPC(size_t max_frames, unwindstack::Maps* maps, unwindstack::Regs* regs, std::shared_ptr process_memory, bool show_pc) 157 | : unwindstack::Unwinder(max_frames, maps, regs, process_memory), show_pc(show_pc) {} 158 | virtual ~UnwinderWithPC() = default; 159 | 160 | bool Init(); 161 | 162 | std::string FormatFrame(size_t frame_num) const; 163 | 164 | protected: 165 | bool show_pc = false; 166 | }; 167 | 168 | std::string UnwinderWithPC::FormatFrame(size_t frame_num) const { 169 | if (frame_num >= frames_.size()) { 170 | return ""; 171 | } 172 | const unwindstack::FrameData& frame = frames_[frame_num]; 173 | 174 | std::string data; 175 | if (show_pc) { 176 | if (ArchIs32Bit(arch_)) { 177 | data += android::base::StringPrintf(" #%02zu pc %08" PRIx64 " %08" PRIx64, frame.num, frame.pc, frame.rel_pc); 178 | } else { 179 | data += android::base::StringPrintf(" #%02zu pc %016" PRIx64 " %016" PRIx64, frame.num, frame.pc, frame.rel_pc); 180 | } 181 | } else { 182 | if (ArchIs32Bit(arch_)) { 183 | data += android::base::StringPrintf(" #%02zu pc %08" PRIx64, frame.num, frame.rel_pc); 184 | } else { 185 | data += android::base::StringPrintf(" #%02zu pc %016" PRIx64, frame.num, frame.rel_pc); 186 | } 187 | } 188 | 189 | auto map_info = frame.map_info; 190 | if (map_info == nullptr) { 191 | // No valid map associated with this frame. 192 | data += " "; 193 | } else if (!map_info->name().empty()) { 194 | data += " "; 195 | data += map_info->GetFullName(); 196 | } else { 197 | data += android::base::StringPrintf(" ", map_info->start()); 198 | } 199 | 200 | if (map_info != nullptr && map_info->elf_start_offset() != 0) { 201 | data += android::base::StringPrintf(" (offset 0x%" PRIx64 ")", map_info->elf_start_offset()); 202 | } 203 | 204 | if (!frame.function_name.empty()) { 205 | char* demangled_name = __cxa_demangle(frame.function_name.c_str(), nullptr, nullptr, nullptr); 206 | if (demangled_name == nullptr) { 207 | data += " ("; 208 | data += frame.function_name; 209 | } else { 210 | data += " ("; 211 | data += demangled_name; 212 | free(demangled_name); 213 | } 214 | if (frame.function_offset != 0) { 215 | data += android::base::StringPrintf("+%" PRId64, frame.function_offset); 216 | } 217 | data += ')'; 218 | } 219 | 220 | if (map_info != nullptr && display_build_id_) { 221 | std::string build_id = map_info->GetPrintableBuildID(); 222 | if (!build_id.empty()) { 223 | data += " (BuildId: " + build_id + ')'; 224 | } 225 | } 226 | return data; 227 | } 228 | 229 | struct UnwindOption { 230 | uint64_t abi; 231 | uint64_t stack_size; 232 | uint64_t dyn_size; 233 | uint64_t reg_mask; 234 | bool show_pc; 235 | }; 236 | 237 | enum ArchType { 238 | ARCH_X86_32, 239 | ARCH_X86_64, 240 | ARCH_ARM, 241 | ARCH_ARM64, 242 | ARCH_UNSUPPORTED, 243 | }; 244 | 245 | class ScopedCurrentArch { 246 | public: 247 | explicit ScopedCurrentArch(ArchType arch) : saved_arch(current_arch) { 248 | current_arch = arch; 249 | } 250 | ~ScopedCurrentArch() { 251 | current_arch = saved_arch; 252 | } 253 | static ArchType GetCurrentArch() { return current_arch; } 254 | 255 | private: 256 | ArchType saved_arch; 257 | static ArchType current_arch; 258 | }; 259 | 260 | ArchType ScopedCurrentArch::current_arch = ARCH_ARM64; 261 | 262 | struct RegSet { 263 | ArchType arch; 264 | uint64_t valid_mask; 265 | uint64_t data[64]; 266 | 267 | RegSet(int abi, uint64_t valid_mask, const uint64_t* valid_regs); 268 | 269 | bool GetRegValue(size_t regno, uint64_t* value) const; 270 | bool GetSpRegValue(uint64_t* value) const; 271 | }; 272 | 273 | ArchType GetArchForAbi(ArchType machine_arch, int abi) { 274 | if (abi == PERF_SAMPLE_REGS_ABI_32) { 275 | if (machine_arch == ARCH_X86_64) { 276 | return ARCH_X86_32; 277 | } 278 | if (machine_arch == ARCH_ARM64) { 279 | return ARCH_ARM; 280 | } 281 | } else if (abi == PERF_SAMPLE_REGS_ABI_64) { 282 | if (machine_arch == ARCH_X86_32) { 283 | return ARCH_X86_64; 284 | } 285 | if (machine_arch == ARCH_ARM) { 286 | return ARCH_ARM64; 287 | } 288 | } 289 | return machine_arch; 290 | } 291 | 292 | RegSet::RegSet(int abi, uint64_t valid_mask, const uint64_t* valid_regs) : valid_mask(valid_mask) { 293 | arch = GetArchForAbi(ScopedCurrentArch::GetCurrentArch(), abi); 294 | memset(data, 0, sizeof(data)); 295 | for (int i = 0, j = 0; i < 64; ++i) { 296 | if ((valid_mask >> i) & 1) { 297 | data[i] = valid_regs[j++]; 298 | } 299 | } 300 | // actually, don't need this 301 | // if (ScopedCurrentArch::GetCurrentArch() == ARCH_ARM64 && abi == PERF_SAMPLE_REGS_ABI_32) { 302 | // // The kernel dumps arm64 regs, but we need arm regs. So map arm64 regs into arm regs. 303 | // data[PERF_REG_ARM_PC] = data[PERF_REG_ARM64_PC]; 304 | // } 305 | } 306 | 307 | bool RegSet::GetRegValue(size_t regno, uint64_t* value) const { 308 | if ((valid_mask >> regno) & 1) { 309 | *value = data[regno]; 310 | return true; 311 | } 312 | return false; 313 | } 314 | 315 | bool RegSet::GetSpRegValue(uint64_t* value) const { 316 | size_t regno; 317 | switch (arch) { 318 | case ARCH_X86_32: 319 | regno = PERF_REG_X86_SP; 320 | break; 321 | case ARCH_X86_64: 322 | regno = PERF_REG_X86_SP; 323 | break; 324 | case ARCH_ARM: 325 | regno = PERF_REG_ARM_SP; 326 | break; 327 | case ARCH_ARM64: 328 | regno = PERF_REG_ARM64_SP; 329 | break; 330 | default: 331 | return false; 332 | } 333 | return GetRegValue(regno, value); 334 | } 335 | 336 | std::string DumpFrames(const UnwinderWithPC& unwinder) { 337 | std::string str; 338 | for (size_t i = 0; i < unwinder.NumFrames(); i++) { 339 | str += unwinder.FormatFrame(i) + "\n"; 340 | } 341 | return str; 342 | } 343 | 344 | unwindstack::Regs* GetBacktraceRegs(const RegSet& regs) { 345 | switch (regs.arch) { 346 | case ARCH_ARM: { 347 | unwindstack::arm_user_regs arm_user_regs; 348 | memset(&arm_user_regs, 0, sizeof(arm_user_regs)); 349 | static_assert(static_cast(unwindstack::ARM_REG_R0) == static_cast(PERF_REG_ARM_R0), 350 | ""); 351 | static_assert( 352 | static_cast(unwindstack::ARM_REG_LAST) == static_cast(PERF_REG_ARM_MAX), ""); 353 | for (size_t i = unwindstack::ARM_REG_R0; i < unwindstack::ARM_REG_LAST; ++i) { 354 | arm_user_regs.regs[i] = static_cast(regs.data[i]); 355 | } 356 | return unwindstack::RegsArm::Read(&arm_user_regs); 357 | } 358 | case ARCH_ARM64: { 359 | unwindstack::arm64_user_regs arm64_user_regs; 360 | memset(&arm64_user_regs, 0, sizeof(arm64_user_regs)); 361 | static_assert( 362 | static_cast(unwindstack::ARM64_REG_R0) == static_cast(PERF_REG_ARM64_X0), ""); 363 | static_assert( 364 | static_cast(unwindstack::ARM64_REG_R30) == static_cast(PERF_REG_ARM64_LR), ""); 365 | memcpy(&arm64_user_regs.regs[unwindstack::ARM64_REG_R0], ®s.data[PERF_REG_ARM64_X0], 366 | sizeof(uint64_t) * (PERF_REG_ARM64_LR - PERF_REG_ARM64_X0 + 1)); 367 | arm64_user_regs.sp = regs.data[PERF_REG_ARM64_SP]; 368 | arm64_user_regs.pc = regs.data[PERF_REG_ARM64_PC]; 369 | auto regs = 370 | static_cast(unwindstack::RegsArm64::Read(&arm64_user_regs)); 371 | uint64_t arm64_pac_mask_ = 0; 372 | regs->SetPACMask(arm64_pac_mask_); 373 | return regs; 374 | } 375 | case ARCH_X86_32: { 376 | unwindstack::x86_user_regs x86_user_regs; 377 | memset(&x86_user_regs, 0, sizeof(x86_user_regs)); 378 | x86_user_regs.eax = static_cast(regs.data[PERF_REG_X86_AX]); 379 | x86_user_regs.ebx = static_cast(regs.data[PERF_REG_X86_BX]); 380 | x86_user_regs.ecx = static_cast(regs.data[PERF_REG_X86_CX]); 381 | x86_user_regs.edx = static_cast(regs.data[PERF_REG_X86_DX]); 382 | x86_user_regs.ebp = static_cast(regs.data[PERF_REG_X86_BP]); 383 | x86_user_regs.edi = static_cast(regs.data[PERF_REG_X86_DI]); 384 | x86_user_regs.esi = static_cast(regs.data[PERF_REG_X86_SI]); 385 | x86_user_regs.esp = static_cast(regs.data[PERF_REG_X86_SP]); 386 | x86_user_regs.eip = static_cast(regs.data[PERF_REG_X86_IP]); 387 | return unwindstack::RegsX86::Read(&x86_user_regs); 388 | } 389 | case ARCH_X86_64: { 390 | unwindstack::x86_64_user_regs x86_64_user_regs; 391 | memset(&x86_64_user_regs, 0, sizeof(x86_64_user_regs)); 392 | x86_64_user_regs.rax = regs.data[PERF_REG_X86_AX]; 393 | x86_64_user_regs.rbx = regs.data[PERF_REG_X86_BX]; 394 | x86_64_user_regs.rcx = regs.data[PERF_REG_X86_CX]; 395 | x86_64_user_regs.rdx = regs.data[PERF_REG_X86_DX]; 396 | x86_64_user_regs.r8 = regs.data[PERF_REG_X86_R8]; 397 | x86_64_user_regs.r9 = regs.data[PERF_REG_X86_R9]; 398 | x86_64_user_regs.r10 = regs.data[PERF_REG_X86_R10]; 399 | x86_64_user_regs.r11 = regs.data[PERF_REG_X86_R11]; 400 | x86_64_user_regs.r12 = regs.data[PERF_REG_X86_R12]; 401 | x86_64_user_regs.r13 = regs.data[PERF_REG_X86_R13]; 402 | x86_64_user_regs.r14 = regs.data[PERF_REG_X86_R14]; 403 | x86_64_user_regs.r15 = regs.data[PERF_REG_X86_R15]; 404 | x86_64_user_regs.rdi = regs.data[PERF_REG_X86_DI]; 405 | x86_64_user_regs.rsi = regs.data[PERF_REG_X86_SI]; 406 | x86_64_user_regs.rbp = regs.data[PERF_REG_X86_BP]; 407 | x86_64_user_regs.rsp = regs.data[PERF_REG_X86_SP]; 408 | x86_64_user_regs.rip = regs.data[PERF_REG_X86_IP]; 409 | return unwindstack::RegsX86_64::Read(&x86_64_user_regs); 410 | } 411 | default: 412 | return nullptr; 413 | } 414 | } 415 | 416 | const char* UnwindCallChain(char* map_buffer, UnwindOption* opt, uint64_t* regs_buf, void* stack_buf) { 417 | const char* result = ""; 418 | // std::cerr << "pid:" << pid << "reg_mask:" << opt->reg_mask << "abi:" << opt->abi << std::endl; 419 | RegSet regs(opt->abi, opt->reg_mask, regs_buf); 420 | 421 | uint64_t sp_reg_value; 422 | if (!regs.GetSpRegValue(&sp_reg_value)) { 423 | std::cerr << "can't get sp reg value"; 424 | return result; 425 | } 426 | 427 | uint64_t stack_addr = sp_reg_value; 428 | size_t stack_size = opt->dyn_size; 429 | 430 | std::unique_ptr unwind_regs(GetBacktraceRegs(regs)); 431 | if (!unwind_regs) { 432 | return result; 433 | } 434 | std::shared_ptr stack_memory = unwindstack::Memory::CreateOfflineMemory( 435 | reinterpret_cast(stack_buf), stack_addr, stack_addr + stack_size 436 | ); 437 | 438 | std::unique_ptr maps; 439 | maps.reset(new unwindstack::BufferMaps(map_buffer)); 440 | maps->Parse(); 441 | 442 | UnwinderWithPC unwinder(512, maps.get(), unwind_regs.get(), stack_memory, opt->show_pc); 443 | // default is true 444 | // unwinder.SetResolveNames(false); 445 | unwinder.Unwind(); 446 | std::string frame_info = DumpFrames(unwinder); 447 | // int len = frame_info.length(); 448 | // send(client_sockfd, &len, 4, 0); 449 | // send(client_sockfd, frame_info.c_str(), len, 0); 450 | result = frame_info.c_str(); 451 | return result; 452 | } 453 | 454 | const char* UnwindCallChainV2(int pid, UnwindOption* opt, uint64_t* regs_buf, void* stack_buf) { 455 | const char* result = ""; 456 | // SetMinimumLogSeverity(android::base::DEBUG); 457 | 458 | RegSet regs(opt->abi, opt->reg_mask, regs_buf); 459 | 460 | uint64_t sp_reg_value; 461 | if (!regs.GetSpRegValue(&sp_reg_value)) { 462 | std::cerr << "can't get sp reg value"; 463 | return result; 464 | } 465 | 466 | uint64_t stack_addr = sp_reg_value; 467 | size_t stack_size = opt->dyn_size; 468 | 469 | std::unique_ptr unwind_regs(GetBacktraceRegs(regs)); 470 | if (!unwind_regs) { 471 | return result; 472 | } 473 | 474 | MyAndroidRemoteUnwinder unwinder((pid_t) pid, opt->show_pc); 475 | unwindstack::AndroidUnwinderData data; 476 | unwindstack::ErrorData error; 477 | 478 | unwinder.SetArch(unwind_regs->Arch()); 479 | unwinder.SetMaxFrames(512); 480 | unwinder.SetDisplayBuildID(false); 481 | 482 | if (!unwinder.Initialize(error)){ 483 | std::cerr << "Initialize failed" << std::endl; 484 | }; 485 | 486 | if (!unwinder.Unwind(unwind_regs.get(), data)){ 487 | std::cerr << "Unwind failed" << std::endl; 488 | }; 489 | 490 | std::string frame_info; 491 | for (const auto& frame : data.frames) { 492 | frame_info += unwinder.FormatFrame(frame) + '\n'; 493 | } 494 | 495 | result = frame_info.c_str(); 496 | return result; 497 | } 498 | } 499 | 500 | __attribute__ ((visibility("default"))) 501 | extern "C" const char* StackPlz(char* map_buffer, void* opt, void* regs_buf, void* stack_buf) { 502 | return unwinddaemon::UnwindCallChain(map_buffer, (unwinddaemon::UnwindOption*) opt, (uint64_t*) regs_buf, stack_buf); 503 | } 504 | 505 | __attribute__ ((visibility("default"))) 506 | extern "C" const char* StackPlzV2(int pid, void* opt, void* regs_buf, void* stack_buf) { 507 | return unwinddaemon::UnwindCallChainV2(pid, (unwinddaemon::UnwindOption*) opt, (uint64_t*) regs_buf, stack_buf); 508 | } -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #if defined(USE_BIONIC_UAPI_HEADERS) 12 | #include 13 | #include 14 | #include 15 | #define perf_event_arm_regs perf_event_arm64_regs 16 | #include 17 | #else 18 | #include 19 | #include 20 | #include 21 | #define perf_event_arm_regs perf_event_arm64_regs 22 | #include 23 | #endif 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | namespace unwinddaemon { 42 | 43 | struct UserRegs { 44 | uint64_t abi; 45 | uint64_t regs[33]; 46 | }; 47 | 48 | struct UserStack { 49 | uint64_t size; 50 | char data[16384]; 51 | uint64_t dyn_size; 52 | }; 53 | 54 | struct DataBuff { 55 | UserRegs user_regs; 56 | UserStack user_stack; 57 | }; 58 | 59 | enum ArchType { 60 | ARCH_X86_32, 61 | ARCH_X86_64, 62 | ARCH_ARM, 63 | ARCH_ARM64, 64 | ARCH_UNSUPPORTED, 65 | }; 66 | 67 | class ScopedCurrentArch { 68 | public: 69 | explicit ScopedCurrentArch(ArchType arch) : saved_arch(current_arch) { 70 | current_arch = arch; 71 | } 72 | ~ScopedCurrentArch() { 73 | current_arch = saved_arch; 74 | } 75 | static ArchType GetCurrentArch() { return current_arch; } 76 | 77 | private: 78 | ArchType saved_arch; 79 | static ArchType current_arch; 80 | }; 81 | 82 | ArchType ScopedCurrentArch::current_arch = ARCH_ARM64; 83 | 84 | struct RegSet { 85 | ArchType arch; 86 | uint64_t valid_mask; 87 | uint64_t data[64]; 88 | 89 | RegSet(int abi, uint64_t valid_mask, const uint64_t* valid_regs); 90 | 91 | bool GetRegValue(size_t regno, uint64_t* value) const; 92 | bool GetSpRegValue(uint64_t* value) const; 93 | }; 94 | 95 | ArchType GetArchForAbi(ArchType machine_arch, int abi) { 96 | if (abi == PERF_SAMPLE_REGS_ABI_32) { 97 | if (machine_arch == ARCH_X86_64) { 98 | return ARCH_X86_32; 99 | } 100 | if (machine_arch == ARCH_ARM64) { 101 | return ARCH_ARM; 102 | } 103 | } else if (abi == PERF_SAMPLE_REGS_ABI_64) { 104 | if (machine_arch == ARCH_X86_32) { 105 | return ARCH_X86_64; 106 | } 107 | if (machine_arch == ARCH_ARM) { 108 | return ARCH_ARM64; 109 | } 110 | } 111 | return machine_arch; 112 | } 113 | 114 | RegSet::RegSet(int abi, uint64_t valid_mask, const uint64_t* valid_regs) : valid_mask(valid_mask) { 115 | arch = GetArchForAbi(ScopedCurrentArch::GetCurrentArch(), abi); 116 | memset(data, 0, sizeof(data)); 117 | for (int i = 0, j = 0; i < 64; ++i) { 118 | if ((valid_mask >> i) & 1) { 119 | data[i] = valid_regs[j++]; 120 | } 121 | } 122 | if (ScopedCurrentArch::GetCurrentArch() == ARCH_ARM64 && abi == PERF_SAMPLE_REGS_ABI_32) { 123 | // The kernel dumps arm64 regs, but we need arm regs. So map arm64 regs into arm regs. 124 | data[PERF_REG_ARM_PC] = data[PERF_REG_ARM64_PC]; 125 | } 126 | } 127 | 128 | bool RegSet::GetRegValue(size_t regno, uint64_t* value) const { 129 | CHECK_LT(regno, 64U); 130 | LOG(DEBUG) << "GetRegValue valid_mask:" << valid_mask << " regno:" << regno; 131 | if ((valid_mask >> regno) & 1) { 132 | *value = data[regno]; 133 | return true; 134 | } 135 | return false; 136 | } 137 | 138 | bool RegSet::GetSpRegValue(uint64_t* value) const { 139 | size_t regno; 140 | switch (arch) { 141 | case ARCH_X86_32: 142 | regno = PERF_REG_X86_SP; 143 | break; 144 | case ARCH_X86_64: 145 | regno = PERF_REG_X86_SP; 146 | break; 147 | case ARCH_ARM: 148 | regno = PERF_REG_ARM_SP; 149 | break; 150 | case ARCH_ARM64: 151 | regno = PERF_REG_ARM64_SP; 152 | break; 153 | default: 154 | return false; 155 | } 156 | return GetRegValue(regno, value); 157 | } 158 | 159 | std::string DumpFrames(const unwindstack::Unwinder& unwinder) { 160 | std::string str; 161 | for (size_t i = 0; i < unwinder.NumFrames(); i++) { 162 | str += unwinder.FormatFrame(i) + "\n"; 163 | } 164 | return str; 165 | } 166 | 167 | unwindstack::Regs* GetBacktraceRegs(const RegSet& regs) { 168 | switch (regs.arch) { 169 | case ARCH_ARM: { 170 | unwindstack::arm_user_regs arm_user_regs; 171 | memset(&arm_user_regs, 0, sizeof(arm_user_regs)); 172 | static_assert(static_cast(unwindstack::ARM_REG_R0) == static_cast(PERF_REG_ARM_R0), 173 | ""); 174 | static_assert( 175 | static_cast(unwindstack::ARM_REG_LAST) == static_cast(PERF_REG_ARM_MAX), ""); 176 | for (size_t i = unwindstack::ARM_REG_R0; i < unwindstack::ARM_REG_LAST; ++i) { 177 | arm_user_regs.regs[i] = static_cast(regs.data[i]); 178 | } 179 | return unwindstack::RegsArm::Read(&arm_user_regs); 180 | } 181 | case ARCH_ARM64: { 182 | unwindstack::arm64_user_regs arm64_user_regs; 183 | memset(&arm64_user_regs, 0, sizeof(arm64_user_regs)); 184 | static_assert( 185 | static_cast(unwindstack::ARM64_REG_R0) == static_cast(PERF_REG_ARM64_X0), ""); 186 | static_assert( 187 | static_cast(unwindstack::ARM64_REG_R30) == static_cast(PERF_REG_ARM64_LR), ""); 188 | memcpy(&arm64_user_regs.regs[unwindstack::ARM64_REG_R0], ®s.data[PERF_REG_ARM64_X0], 189 | sizeof(uint64_t) * (PERF_REG_ARM64_LR - PERF_REG_ARM64_X0 + 1)); 190 | arm64_user_regs.sp = regs.data[PERF_REG_ARM64_SP]; 191 | arm64_user_regs.pc = regs.data[PERF_REG_ARM64_PC]; 192 | auto regs = 193 | static_cast(unwindstack::RegsArm64::Read(&arm64_user_regs)); 194 | uint64_t arm64_pac_mask_ = 0; 195 | regs->SetPACMask(arm64_pac_mask_); 196 | return regs; 197 | } 198 | case ARCH_X86_32: { 199 | unwindstack::x86_user_regs x86_user_regs; 200 | memset(&x86_user_regs, 0, sizeof(x86_user_regs)); 201 | x86_user_regs.eax = static_cast(regs.data[PERF_REG_X86_AX]); 202 | x86_user_regs.ebx = static_cast(regs.data[PERF_REG_X86_BX]); 203 | x86_user_regs.ecx = static_cast(regs.data[PERF_REG_X86_CX]); 204 | x86_user_regs.edx = static_cast(regs.data[PERF_REG_X86_DX]); 205 | x86_user_regs.ebp = static_cast(regs.data[PERF_REG_X86_BP]); 206 | x86_user_regs.edi = static_cast(regs.data[PERF_REG_X86_DI]); 207 | x86_user_regs.esi = static_cast(regs.data[PERF_REG_X86_SI]); 208 | x86_user_regs.esp = static_cast(regs.data[PERF_REG_X86_SP]); 209 | x86_user_regs.eip = static_cast(regs.data[PERF_REG_X86_IP]); 210 | return unwindstack::RegsX86::Read(&x86_user_regs); 211 | } 212 | case ARCH_X86_64: { 213 | unwindstack::x86_64_user_regs x86_64_user_regs; 214 | memset(&x86_64_user_regs, 0, sizeof(x86_64_user_regs)); 215 | x86_64_user_regs.rax = regs.data[PERF_REG_X86_AX]; 216 | x86_64_user_regs.rbx = regs.data[PERF_REG_X86_BX]; 217 | x86_64_user_regs.rcx = regs.data[PERF_REG_X86_CX]; 218 | x86_64_user_regs.rdx = regs.data[PERF_REG_X86_DX]; 219 | x86_64_user_regs.r8 = regs.data[PERF_REG_X86_R8]; 220 | x86_64_user_regs.r9 = regs.data[PERF_REG_X86_R9]; 221 | x86_64_user_regs.r10 = regs.data[PERF_REG_X86_R10]; 222 | x86_64_user_regs.r11 = regs.data[PERF_REG_X86_R11]; 223 | x86_64_user_regs.r12 = regs.data[PERF_REG_X86_R12]; 224 | x86_64_user_regs.r13 = regs.data[PERF_REG_X86_R13]; 225 | x86_64_user_regs.r14 = regs.data[PERF_REG_X86_R14]; 226 | x86_64_user_regs.r15 = regs.data[PERF_REG_X86_R15]; 227 | x86_64_user_regs.rdi = regs.data[PERF_REG_X86_DI]; 228 | x86_64_user_regs.rsi = regs.data[PERF_REG_X86_SI]; 229 | x86_64_user_regs.rbp = regs.data[PERF_REG_X86_BP]; 230 | x86_64_user_regs.rsp = regs.data[PERF_REG_X86_SP]; 231 | x86_64_user_regs.rip = regs.data[PERF_REG_X86_IP]; 232 | return unwindstack::RegsX86_64::Read(&x86_64_user_regs); 233 | } 234 | default: 235 | return nullptr; 236 | } 237 | } 238 | 239 | bool UnwindCallChain(int pid, uint64_t reg_mask, DataBuff *data_buf, int client_sockfd) { 240 | RegSet regs(data_buf->user_regs.abi, reg_mask, data_buf->user_regs.regs); 241 | LOG(DEBUG) << "abi:" << data_buf->user_regs.abi << ", arch:" << regs.arch; 242 | 243 | uint64_t sp_reg_value; 244 | if (!regs.GetSpRegValue(&sp_reg_value)) { 245 | std::cerr << "can't get sp reg value"; 246 | return false; 247 | } 248 | LOG(DEBUG) << "sp_reg_value: 0x" << std::hex << sp_reg_value; 249 | 250 | uint64_t stack_addr = sp_reg_value; 251 | const char *stack = data_buf->user_stack.data; 252 | size_t stack_size = data_buf->user_stack.dyn_size; 253 | 254 | std::unique_ptr unwind_regs(GetBacktraceRegs(regs)); 255 | if (!unwind_regs) { 256 | return false; 257 | } 258 | std::shared_ptr stack_memory = unwindstack::Memory::CreateOfflineMemory( 259 | reinterpret_cast(stack), stack_addr, stack_addr + stack_size 260 | ); 261 | 262 | std::string map_buffer; 263 | std::unique_ptr maps; 264 | std::string proc_map_file = "/proc/" + std::to_string(pid) + "/maps"; 265 | android::base::ReadFileToString(proc_map_file, &map_buffer); 266 | maps.reset(new unwindstack::BufferMaps(map_buffer.c_str())); 267 | maps->Parse(); 268 | unwindstack::Unwinder unwinder(512, maps.get(), unwind_regs.get(), stack_memory); 269 | // default is true 270 | // unwinder.SetResolveNames(false); 271 | unwinder.Unwind(); 272 | std::string frame_info = DumpFrames(unwinder); 273 | // LOG(DEBUG) << "frame_info:" << frame_info; 274 | int len = frame_info.length(); 275 | send(client_sockfd, &len, 4, 0); 276 | send(client_sockfd, frame_info.c_str(), len, 0); 277 | return true; 278 | } 279 | } 280 | 281 | static std::map log_severity_map = { 282 | {"verbose", android::base::VERBOSE}, {"debug", android::base::DEBUG}, 283 | {"info", android::base::INFO}, {"warning", android::base::WARNING}, 284 | {"error", android::base::ERROR}, {"fatal", android::base::FATAL}, 285 | }; 286 | 287 | bool GetLogSeverity(const std::string& name, android::base::LogSeverity* severity) { 288 | auto it = log_severity_map.find(name); 289 | if (it != log_severity_map.end()) { 290 | *severity = it->second; 291 | return true; 292 | } 293 | return false; 294 | } 295 | 296 | static void StderrLogger(android::base::LogId, android::base::LogSeverity severity, const char*, 297 | const char* file, unsigned int line, const char* message) { 298 | static const char log_characters[] = "VDIWEFF"; 299 | char severity_char = log_characters[severity]; 300 | fprintf(stderr, "%c %s:%u] %s\n", severity_char, file, line, message); 301 | } 302 | 303 | int main(int argc, char** argv) { 304 | 305 | android::base::InitLogging(argv, StderrLogger); 306 | android::base::LogSeverity log_severity = android::base::DEBUG; 307 | for (int i = 1; i < argc; ++i) { 308 | if (strcmp(argv[i], "--log") == 0) { 309 | if (i + 1 < argc) { 310 | ++i; 311 | if (!GetLogSeverity(argv[i], &log_severity)) { 312 | LOG(ERROR) << "Unknown log severity: " << argv[i]; 313 | return 1; 314 | } 315 | } else { 316 | LOG(WARNING) << "Missing argument for --log option.\n"; 317 | } 318 | } 319 | } 320 | android::base::ScopedLogSeverity severity(log_severity); 321 | 322 | int server_sockfd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); 323 | if (server_sockfd < 0) { 324 | LOG(DEBUG) << "create server socket failed"; 325 | return 1; 326 | } 327 | LOG(DEBUG) << "create server socket end, server_sockfd=" << server_sockfd; 328 | 329 | struct sockaddr_un mysock_addr; 330 | mysock_addr.sun_family = PF_UNIX; 331 | strcpy(mysock_addr.sun_path, "/dev/socket/mysock"); 332 | unlink(mysock_addr.sun_path); 333 | 334 | int len = strlen(mysock_addr.sun_path) + sizeof(mysock_addr.sun_family); 335 | int bind_status = bind(server_sockfd, (struct sockaddr *)&mysock_addr, len); 336 | if (bind_status < 0) { 337 | LOG(DEBUG) << "bind server failed, path=" << mysock_addr.sun_path; 338 | return 1; 339 | } 340 | 341 | int listen_status = listen(server_sockfd, 5); 342 | if (listen_status < 0) { 343 | LOG(DEBUG) << "listen failed"; 344 | return 1; 345 | } 346 | 347 | int client_sockfd; 348 | struct sockaddr_un remote_addr; 349 | socklen_t remote_addr_len; 350 | while (true) { 351 | client_sockfd = accept(server_sockfd, (struct sockaddr *)&remote_addr, &remote_addr_len); 352 | if(client_sockfd < 0) { 353 | break; 354 | }; 355 | LOG(DEBUG) << "accept fd:" << client_sockfd; 356 | 357 | // recv 4 byte pid 358 | uint8_t pid_buffer[4]; 359 | int recv_len = recv(client_sockfd, &pid_buffer, 4, 0); 360 | if (recv_len != 4) { 361 | LOG(DEBUG) << "read pid failed, recv_len=" << recv_len; 362 | break; 363 | } 364 | int pid = *(int *)pid_buffer; 365 | LOG(DEBUG) << "read pid:" << pid; 366 | 367 | // recv 4 byte size 368 | uint8_t size_buffer[4]; 369 | recv_len = recv(client_sockfd, &size_buffer, 4, 0); 370 | if (recv_len != 4) { 371 | LOG(DEBUG) << "read size failed, recv_len=" << recv_len; 372 | break; 373 | } 374 | int size = *(int *)size_buffer; 375 | LOG(DEBUG) << "read size:" << size; 376 | 377 | // max size 32k 378 | uint8_t full_buffer[1024 * 32]; 379 | uint8_t tmp_buffer[1024]; 380 | int total_len = 0; 381 | 382 | while (true) { 383 | recv_len = recv(client_sockfd, &tmp_buffer, 1024, 0); 384 | memcpy(full_buffer + total_len, tmp_buffer, recv_len); 385 | if (recv_len > 0) { 386 | total_len += recv_len; 387 | } else { 388 | break; 389 | } 390 | if (total_len >= size) { 391 | break; 392 | } 393 | } 394 | if (size != total_len) { 395 | LOG(DEBUG) << "size:" << size <<" not equal total_len:" << total_len; 396 | } 397 | 398 | LOG(DEBUG) << "recv DataBuff total_len:" << total_len; 399 | if (total_len > 0) { 400 | uint64_t reg_mask = ((1ULL << 33) - 1); 401 | unwinddaemon::DataBuff* data_buff = (unwinddaemon::DataBuff*) full_buffer; 402 | unwinddaemon::UnwindCallChain(pid, reg_mask, data_buff, client_sockfd); 403 | } 404 | } 405 | close(client_sockfd); 406 | } 407 | -------------------------------------------------------------------------------- /shim_files/liblog/include/android/log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | /** 20 | * @addtogroup Logging 21 | * @{ 22 | */ 23 | 24 | /** 25 | * \file 26 | * 27 | * Support routines to send messages to the Android log buffer, 28 | * which can later be accessed through the `logcat` utility. 29 | * 30 | * Each log message must have 31 | * - a priority 32 | * - a log tag 33 | * - some text 34 | * 35 | * The tag normally corresponds to the component that emits the log message, 36 | * and should be reasonably small. 37 | * 38 | * Log message text may be truncated to less than an implementation-specific 39 | * limit (1023 bytes). 40 | * 41 | * Note that a newline character ("\n") will be appended automatically to your 42 | * log message, if not already there. It is not possible to send several 43 | * messages and have them appear on a single line in logcat. 44 | * 45 | * Please use logging in moderation: 46 | * 47 | * - Sending log messages eats CPU and slow down your application and the 48 | * system. 49 | * 50 | * - The circular log buffer is pretty small, so sending many messages 51 | * will hide other important log messages. 52 | * 53 | * - In release builds, only send log messages to account for exceptional 54 | * conditions. 55 | */ 56 | 57 | #include 58 | #include 59 | #include 60 | #include 61 | 62 | #if !defined(__BIONIC__) && !defined(__INTRODUCED_IN) 63 | #define __INTRODUCED_IN(x) 64 | #endif 65 | 66 | #ifdef __cplusplus 67 | extern "C" { 68 | #endif 69 | 70 | /** 71 | * Android log priority values, in increasing order of priority. 72 | */ 73 | typedef enum android_LogPriority { 74 | /** For internal use only. */ 75 | ANDROID_LOG_UNKNOWN = 0, 76 | /** The default priority, for internal use only. */ 77 | ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */ 78 | /** Verbose logging. Should typically be disabled for a release apk. */ 79 | ANDROID_LOG_VERBOSE, 80 | /** Debug logging. Should typically be disabled for a release apk. */ 81 | ANDROID_LOG_DEBUG, 82 | /** Informational logging. Should typically be disabled for a release apk. */ 83 | ANDROID_LOG_INFO, 84 | /** Warning logging. For use with recoverable failures. */ 85 | ANDROID_LOG_WARN, 86 | /** Error logging. For use with unrecoverable failures. */ 87 | ANDROID_LOG_ERROR, 88 | /** Fatal logging. For use when aborting. */ 89 | ANDROID_LOG_FATAL, 90 | /** For internal use only. */ 91 | ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */ 92 | } android_LogPriority; 93 | 94 | /** 95 | * Writes the constant string `text` to the log, with priority `prio` and tag 96 | * `tag`. 97 | */ 98 | int __android_log_write(int prio, const char* tag, const char* text); 99 | 100 | /** 101 | * Writes a formatted string to the log, with priority `prio` and tag `tag`. 102 | * The details of formatting are the same as for 103 | * [printf(3)](http://man7.org/linux/man-pages/man3/printf.3.html). 104 | */ 105 | int __android_log_print(int prio, const char* tag, const char* fmt, ...) 106 | __attribute__((__format__(printf, 3, 4))); 107 | 108 | /** 109 | * Equivalent to `__android_log_print`, but taking a `va_list`. 110 | * (If `__android_log_print` is like `printf`, this is like `vprintf`.) 111 | */ 112 | int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) 113 | __attribute__((__format__(printf, 3, 0))); 114 | 115 | /** 116 | * Writes an assertion failure to the log (as `ANDROID_LOG_FATAL`) and to 117 | * stderr, before calling 118 | * [abort(3)](http://man7.org/linux/man-pages/man3/abort.3.html). 119 | * 120 | * If `fmt` is non-null, `cond` is unused. If `fmt` is null, the string 121 | * `Assertion failed: %s` is used with `cond` as the string argument. 122 | * If both `fmt` and `cond` are null, a default string is provided. 123 | * 124 | * Most callers should use 125 | * [assert(3)](http://man7.org/linux/man-pages/man3/assert.3.html) from 126 | * `<assert.h>` instead, or the `__assert` and `__assert2` functions 127 | * provided by bionic if more control is needed. They support automatically 128 | * including the source filename and line number more conveniently than this 129 | * function. 130 | */ 131 | void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...) 132 | __attribute__((__noreturn__)) __attribute__((__format__(printf, 3, 4))); 133 | 134 | /** 135 | * Identifies a specific log buffer for __android_log_buf_write() 136 | * and __android_log_buf_print(). 137 | */ 138 | typedef enum log_id { 139 | LOG_ID_MIN = 0, 140 | 141 | /** The main log buffer. This is the only log buffer available to apps. */ 142 | LOG_ID_MAIN = 0, 143 | /** The radio log buffer. */ 144 | LOG_ID_RADIO = 1, 145 | /** The event log buffer. */ 146 | LOG_ID_EVENTS = 2, 147 | /** The system log buffer. */ 148 | LOG_ID_SYSTEM = 3, 149 | /** The crash log buffer. */ 150 | LOG_ID_CRASH = 4, 151 | /** The statistics log buffer. */ 152 | LOG_ID_STATS = 5, 153 | /** The security log buffer. */ 154 | LOG_ID_SECURITY = 6, 155 | /** The kernel log buffer. */ 156 | LOG_ID_KERNEL = 7, 157 | 158 | LOG_ID_MAX, 159 | 160 | /** Let the logging function choose the best log target. */ 161 | LOG_ID_DEFAULT = 0x7FFFFFFF 162 | } log_id_t; 163 | 164 | /** 165 | * Writes the constant string `text` to the log buffer `id`, 166 | * with priority `prio` and tag `tag`. 167 | * 168 | * Apps should use __android_log_write() instead. 169 | */ 170 | int __android_log_buf_write(int bufID, int prio, const char* tag, const char* text); 171 | 172 | /** 173 | * Writes a formatted string to log buffer `id`, 174 | * with priority `prio` and tag `tag`. 175 | * The details of formatting are the same as for 176 | * [printf(3)](http://man7.org/linux/man-pages/man3/printf.3.html). 177 | * 178 | * Apps should use __android_log_print() instead. 179 | */ 180 | int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...) 181 | __attribute__((__format__(printf, 4, 5))); 182 | 183 | /** 184 | * Logger data struct used for writing log messages to liblog via __android_log_write_logger_data() 185 | * and sending log messages to user defined loggers specified in __android_log_set_logger(). 186 | */ 187 | struct __android_log_message { 188 | /** Must be set to sizeof(__android_log_message) and is used for versioning. */ 189 | size_t struct_size; 190 | 191 | /** {@link log_id_t} values. */ 192 | int32_t buffer_id; 193 | 194 | /** {@link android_LogPriority} values. */ 195 | int32_t priority; 196 | 197 | /** The tag for the log message. */ 198 | const char* tag; 199 | 200 | /** Optional file name, may be set to nullptr. */ 201 | const char* file; 202 | 203 | /** Optional line number, ignore if file is nullptr. */ 204 | uint32_t line; 205 | 206 | /** The log message itself. */ 207 | const char* message; 208 | }; 209 | 210 | /** 211 | * Prototype for the 'logger' function that is called for every log message. 212 | */ 213 | typedef void (*__android_logger_function)(const struct __android_log_message* log_message); 214 | /** 215 | * Prototype for the 'abort' function that is called when liblog will abort due to 216 | * __android_log_assert() failures. 217 | */ 218 | typedef void (*__android_aborter_function)(const char* abort_message); 219 | 220 | #if __ANDROID_API__ >= 30 221 | 222 | /** 223 | * Writes the log message specified by log_message. log_message includes additional file name and 224 | * line number information that a logger may use. log_message is versioned for backwards 225 | * compatibility. 226 | * This assumes that loggability has already been checked through __android_log_is_loggable(). 227 | * Higher level logging libraries, such as libbase, first check loggability, then format their 228 | * buffers, then pass the message to liblog via this function, and therefore we do not want to 229 | * duplicate the loggability check here. 230 | * 231 | * @param log_message the log message itself, see __android_log_message. 232 | * 233 | * Available since API level 30. 234 | */ 235 | void __android_log_write_log_message(struct __android_log_message* log_message) __INTRODUCED_IN(30); 236 | 237 | /** 238 | * Sets a user defined logger function. All log messages sent to liblog will be set to the 239 | * function pointer specified by logger for processing. It is not expected that log messages are 240 | * already terminated with a new line. This function should add new lines if required for line 241 | * separation. 242 | * 243 | * @param logger the new function that will handle log messages. 244 | * 245 | * Available since API level 30. 246 | */ 247 | void __android_log_set_logger(__android_logger_function logger) __INTRODUCED_IN(30); 248 | 249 | /** 250 | * Writes the log message to logd. This is an __android_logger_function and can be provided to 251 | * __android_log_set_logger(). It is the default logger when running liblog on a device. 252 | * 253 | * @param log_message the log message to write, see __android_log_message. 254 | * 255 | * Available since API level 30. 256 | */ 257 | void __android_log_logd_logger(const struct __android_log_message* log_message) __INTRODUCED_IN(30); 258 | 259 | /** 260 | * Writes the log message to stderr. This is an __android_logger_function and can be provided to 261 | * __android_log_set_logger(). It is the default logger when running liblog on host. 262 | * 263 | * @param log_message the log message to write, see __android_log_message. 264 | * 265 | * Available since API level 30. 266 | */ 267 | void __android_log_stderr_logger(const struct __android_log_message* log_message) 268 | __INTRODUCED_IN(30); 269 | 270 | /** 271 | * Sets a user defined aborter function that is called for __android_log_assert() failures. This 272 | * user defined aborter function is highly recommended to abort and be noreturn, but is not strictly 273 | * required to. 274 | * 275 | * @param aborter the new aborter function, see __android_aborter_function. 276 | * 277 | * Available since API level 30. 278 | */ 279 | void __android_log_set_aborter(__android_aborter_function aborter) __INTRODUCED_IN(30); 280 | 281 | /** 282 | * Calls the stored aborter function. This allows for other logging libraries to use the same 283 | * aborter function by calling this function in liblog. 284 | * 285 | * @param abort_message an additional message supplied when aborting, for example this is used to 286 | * call android_set_abort_message() in __android_log_default_aborter(). 287 | * 288 | * Available since API level 30. 289 | */ 290 | void __android_log_call_aborter(const char* abort_message) __INTRODUCED_IN(30); 291 | 292 | /** 293 | * Sets android_set_abort_message() on device then aborts(). This is the default aborter. 294 | * 295 | * @param abort_message an additional message supplied when aborting. This functions calls 296 | * android_set_abort_message() with its contents. 297 | * 298 | * Available since API level 30. 299 | */ 300 | void __android_log_default_aborter(const char* abort_message) __attribute__((noreturn)) 301 | __INTRODUCED_IN(30); 302 | 303 | /** 304 | * Use the per-tag properties "log.tag." along with the minimum priority from 305 | * __android_log_set_minimum_priority() to determine if a log message with a given prio and tag will 306 | * be printed. A non-zero result indicates yes, zero indicates false. 307 | * 308 | * If both a priority for a tag and a minimum priority are set by 309 | * __android_log_set_minimum_priority(), then the lowest of the two values are to determine the 310 | * minimum priority needed to log. If only one is set, then that value is used to determine the 311 | * minimum priority needed. If none are set, then default_priority is used. 312 | * 313 | * @param prio the priority to test, takes android_LogPriority values. 314 | * @param tag the tag to test. 315 | * @param default_prio the default priority to use if no properties or minimum priority are set. 316 | * @return an integer where 1 indicates that the message is loggable and 0 indicates that it is not. 317 | * 318 | * Available since API level 30. 319 | */ 320 | int __android_log_is_loggable(int prio, const char* tag, int default_prio) __INTRODUCED_IN(30); 321 | 322 | /** 323 | * Use the per-tag properties "log.tag." along with the minimum priority from 324 | * __android_log_set_minimum_priority() to determine if a log message with a given prio and tag will 325 | * be printed. A non-zero result indicates yes, zero indicates false. 326 | * 327 | * If both a priority for a tag and a minimum priority are set by 328 | * __android_log_set_minimum_priority(), then the lowest of the two values are to determine the 329 | * minimum priority needed to log. If only one is set, then that value is used to determine the 330 | * minimum priority needed. If none are set, then default_priority is used. 331 | * 332 | * @param prio the priority to test, takes android_LogPriority values. 333 | * @param tag the tag to test. 334 | * @param len the length of the tag. 335 | * @param default_prio the default priority to use if no properties or minimum priority are set. 336 | * @return an integer where 1 indicates that the message is loggable and 0 indicates that it is not. 337 | * 338 | * Available since API level 30. 339 | */ 340 | int __android_log_is_loggable_len(int prio, const char* tag, size_t len, int default_prio) 341 | __INTRODUCED_IN(30); 342 | 343 | /** 344 | * Sets the minimum priority that will be logged for this process. 345 | * 346 | * @param priority the new minimum priority to set, takes android_LogPriority values. 347 | * @return the previous set minimum priority as android_LogPriority values, or 348 | * ANDROID_LOG_DEFAULT if none was set. 349 | * 350 | * Available since API level 30. 351 | */ 352 | int32_t __android_log_set_minimum_priority(int32_t priority) __INTRODUCED_IN(30); 353 | 354 | /** 355 | * Gets the minimum priority that will be logged for this process. If none has been set by a 356 | * previous __android_log_set_minimum_priority() call, this returns ANDROID_LOG_DEFAULT. 357 | * 358 | * @return the current minimum priority as android_LogPriority values, or 359 | * ANDROID_LOG_DEFAULT if none is set. 360 | * 361 | * Available since API level 30. 362 | */ 363 | int32_t __android_log_get_minimum_priority(void) __INTRODUCED_IN(30); 364 | 365 | /** 366 | * Sets the default tag if no tag is provided when writing a log message. Defaults to 367 | * getprogname(). This truncates tag to the maximum log message size, though appropriate tags 368 | * should be much smaller. 369 | * 370 | * @param tag the new log tag. 371 | * 372 | * Available since API level 30. 373 | */ 374 | void __android_log_set_default_tag(const char* tag) __INTRODUCED_IN(30); 375 | 376 | #else 377 | 378 | void __android_log_write_log_message(struct __android_log_message* log_message); 379 | void __android_log_set_logger(__android_logger_function logger); 380 | void __android_log_logd_logger(const struct __android_log_message* log_message); 381 | void __android_log_stderr_logger(const struct __android_log_message* log_message); 382 | void __android_log_set_aborter(__android_aborter_function aborter); 383 | void __android_log_call_aborter(const char* abort_message); 384 | void __android_log_default_aborter(const char* abort_message) __attribute__((noreturn)); 385 | int __android_log_is_loggable(int prio, const char* tag, int default_prio); 386 | int __android_log_is_loggable_len(int prio, const char* tag, size_t len, int default_prio); 387 | int32_t __android_log_set_minimum_priority(int32_t priority); 388 | int32_t __android_log_get_minimum_priority(void); 389 | void __android_log_set_default_tag(const char* tag); 390 | 391 | #endif 392 | 393 | #ifdef __cplusplus 394 | } 395 | #endif 396 | 397 | /** @} */ 398 | -------------------------------------------------------------------------------- /shim_files/liblog/include/log/event_tag_map.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | #define EVENT_TAG_MAP_FILE "/system/etc/event-log-tags" 26 | 27 | struct EventTagMap; 28 | typedef struct EventTagMap EventTagMap; 29 | 30 | /* 31 | * Open the specified file as an event log tag map. 32 | * 33 | * Returns NULL on failure. 34 | */ 35 | EventTagMap* android_openEventTagMap(const char* fileName); 36 | 37 | /* 38 | * Close the map. 39 | */ 40 | void android_closeEventTagMap(EventTagMap* map); 41 | 42 | /* 43 | * Look up a tag by index. Returns the tag string & string length, or NULL if 44 | * not found. Returned string is not guaranteed to be nul terminated. 45 | */ 46 | const char* android_lookupEventTag_len(const EventTagMap* map, size_t* len, 47 | unsigned int tag); 48 | 49 | /* 50 | * Look up a format by index. Returns the format string & string length, 51 | * or NULL if not found. Returned string is not guaranteed to be nul terminated. 52 | */ 53 | const char* android_lookupEventFormat_len(const EventTagMap* map, size_t* len, 54 | unsigned int tag); 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | -------------------------------------------------------------------------------- /shim_files/liblog/include/log/log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | /* Too many in the ecosystem assume these are included */ 20 | #if !defined(_WIN32) 21 | #include 22 | #endif 23 | #include /* uint16_t, int32_t */ 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | /* 41 | * LOG_TAG is the local tag used for the following simplified 42 | * logging macros. You can change this preprocessor definition 43 | * before using the other macros to change the tag. 44 | */ 45 | 46 | #ifndef LOG_TAG 47 | #define LOG_TAG NULL 48 | #endif 49 | 50 | /* 51 | * Normally we strip the effects of ALOGV (VERBOSE messages), 52 | * LOG_FATAL and LOG_FATAL_IF (FATAL assert messages) from the 53 | * release builds be defining NDEBUG. You can modify this (for 54 | * example with "#define LOG_NDEBUG 0" at the top of your source 55 | * file) to change that behavior. 56 | */ 57 | 58 | #ifndef LOG_NDEBUG 59 | #ifdef NDEBUG 60 | #define LOG_NDEBUG 1 61 | #else 62 | #define LOG_NDEBUG 0 63 | #endif 64 | #endif 65 | 66 | /* 67 | * The maximum size of the log entry payload that can be 68 | * written to the logger. An attempt to write more than 69 | * this amount will result in a truncated log entry. 70 | */ 71 | #define LOGGER_ENTRY_MAX_PAYLOAD 4068 72 | 73 | /* 74 | * Event logging. 75 | */ 76 | 77 | /* 78 | * The following should not be used directly. 79 | */ 80 | 81 | int __android_log_bwrite(int32_t tag, const void* payload, size_t len); 82 | int __android_log_btwrite(int32_t tag, char type, const void* payload, 83 | size_t len); 84 | int __android_log_bswrite(int32_t tag, const char* payload); 85 | 86 | int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len); 87 | 88 | #define android_bWriteLog(tag, payload, len) \ 89 | __android_log_bwrite(tag, payload, len) 90 | #define android_btWriteLog(tag, type, payload, len) \ 91 | __android_log_btwrite(tag, type, payload, len) 92 | 93 | /* 94 | * Event log entry types. 95 | */ 96 | typedef enum { 97 | /* Special markers for android_log_list_element type */ 98 | EVENT_TYPE_LIST_STOP = '\n', /* declare end of list */ 99 | EVENT_TYPE_UNKNOWN = '?', /* protocol error */ 100 | 101 | /* must match with declaration in java/android/android/util/EventLog.java */ 102 | EVENT_TYPE_INT = 0, /* int32_t */ 103 | EVENT_TYPE_LONG = 1, /* int64_t */ 104 | EVENT_TYPE_STRING = 2, 105 | EVENT_TYPE_LIST = 3, 106 | EVENT_TYPE_FLOAT = 4, 107 | } AndroidEventLogType; 108 | 109 | #ifndef LOG_EVENT_INT 110 | #define LOG_EVENT_INT(_tag, _value) \ 111 | { \ 112 | int intBuf = _value; \ 113 | (void)android_btWriteLog(_tag, EVENT_TYPE_INT, &intBuf, sizeof(intBuf)); \ 114 | } 115 | #endif 116 | #ifndef LOG_EVENT_LONG 117 | #define LOG_EVENT_LONG(_tag, _value) \ 118 | { \ 119 | long long longBuf = _value; \ 120 | (void)android_btWriteLog(_tag, EVENT_TYPE_LONG, &longBuf, sizeof(longBuf)); \ 121 | } 122 | #endif 123 | #ifndef LOG_EVENT_FLOAT 124 | #define LOG_EVENT_FLOAT(_tag, _value) \ 125 | { \ 126 | float floatBuf = _value; \ 127 | (void)android_btWriteLog(_tag, EVENT_TYPE_FLOAT, &floatBuf, \ 128 | sizeof(floatBuf)); \ 129 | } 130 | #endif 131 | #ifndef LOG_EVENT_STRING 132 | #define LOG_EVENT_STRING(_tag, _value) \ 133 | (void)__android_log_bswrite(_tag, _value); 134 | #endif 135 | 136 | /* --------------------------------------------------------------------- */ 137 | 138 | /* 139 | * Release any logger resources (a new log write will immediately re-acquire) 140 | * 141 | * This is specifically meant to be used by Zygote to close open file descriptors after fork() 142 | * and before specialization. O_CLOEXEC is used on file descriptors, so they will be closed upon 143 | * exec() in normal use cases. 144 | * 145 | * Note that this is not safe to call from a multi-threaded program. 146 | */ 147 | void __android_log_close(void); 148 | 149 | #ifdef __cplusplus 150 | } 151 | #endif 152 | -------------------------------------------------------------------------------- /shim_files/liblog/include/log/log_event_list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | #ifdef __cplusplus 23 | #include 24 | #endif 25 | 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | /* For manipulating lists of events. */ 33 | 34 | #define ANDROID_MAX_LIST_NEST_DEPTH 8 35 | 36 | /* 37 | * The opaque context used to manipulate lists of events. 38 | */ 39 | typedef struct android_log_context_internal* android_log_context; 40 | 41 | /* 42 | * Elements returned when reading a list of events. 43 | */ 44 | typedef struct { 45 | AndroidEventLogType type; 46 | uint16_t complete; 47 | uint16_t len; 48 | union { 49 | int32_t int32; 50 | int64_t int64; 51 | char* string; 52 | float float32; 53 | } data; 54 | } android_log_list_element; 55 | 56 | /* 57 | * Creates a context associated with an event tag to write elements to 58 | * the list of events. 59 | */ 60 | android_log_context create_android_logger(uint32_t tag); 61 | 62 | /* All lists must be braced by a begin and end call */ 63 | /* 64 | * NB: If the first level braces are missing when specifying multiple 65 | * elements, we will manufacturer a list to embrace it for your API 66 | * convenience. For a single element, it will remain solitary. 67 | */ 68 | int android_log_write_list_begin(android_log_context ctx); 69 | int android_log_write_list_end(android_log_context ctx); 70 | 71 | int android_log_write_int32(android_log_context ctx, int32_t value); 72 | int android_log_write_int64(android_log_context ctx, int64_t value); 73 | int android_log_write_string8(android_log_context ctx, const char* value); 74 | int android_log_write_string8_len(android_log_context ctx, const char* value, 75 | size_t maxlen); 76 | int android_log_write_float32(android_log_context ctx, float value); 77 | 78 | /* Submit the composed list context to the specified logger id */ 79 | /* NB: LOG_ID_EVENTS and LOG_ID_SECURITY only valid binary buffers */ 80 | int android_log_write_list(android_log_context ctx, log_id_t id); 81 | 82 | /* 83 | * Creates a context from a raw buffer representing a list of events to be read. 84 | */ 85 | android_log_context create_android_log_parser(const char* msg, size_t len); 86 | 87 | android_log_list_element android_log_read_next(android_log_context ctx); 88 | android_log_list_element android_log_peek_next(android_log_context ctx); 89 | 90 | /* Reset writer context */ 91 | int android_log_reset(android_log_context ctx); 92 | 93 | /* Reset reader context */ 94 | int android_log_parser_reset(android_log_context ctx, 95 | const char* msg, size_t len); 96 | 97 | /* Finished with reader or writer context */ 98 | int android_log_destroy(android_log_context* ctx); 99 | 100 | #ifdef __cplusplus 101 | /* android_log_list C++ helpers */ 102 | extern "C++" { 103 | class android_log_event_list { 104 | private: 105 | android_log_context ctx; 106 | int ret; 107 | 108 | android_log_event_list(const android_log_event_list&) = delete; 109 | void operator=(const android_log_event_list&) = delete; 110 | 111 | public: 112 | explicit android_log_event_list(int tag) : ret(0) { 113 | ctx = create_android_logger(static_cast(tag)); 114 | } 115 | ~android_log_event_list() { 116 | android_log_destroy(&ctx); 117 | } 118 | 119 | int close() { 120 | int retval = android_log_destroy(&ctx); 121 | if (retval < 0) ret = retval; 122 | return retval; 123 | } 124 | 125 | /* To allow above C calls to use this class as parameter */ 126 | operator android_log_context() const { 127 | return ctx; 128 | } 129 | 130 | /* return errors or transmit status */ 131 | int status() const { 132 | return ret; 133 | } 134 | 135 | int begin() { 136 | int retval = android_log_write_list_begin(ctx); 137 | if (retval < 0) ret = retval; 138 | return ret; 139 | } 140 | int end() { 141 | int retval = android_log_write_list_end(ctx); 142 | if (retval < 0) ret = retval; 143 | return ret; 144 | } 145 | 146 | android_log_event_list& operator<<(int32_t value) { 147 | int retval = android_log_write_int32(ctx, value); 148 | if (retval < 0) ret = retval; 149 | return *this; 150 | } 151 | 152 | android_log_event_list& operator<<(uint32_t value) { 153 | int retval = android_log_write_int32(ctx, static_cast(value)); 154 | if (retval < 0) ret = retval; 155 | return *this; 156 | } 157 | 158 | android_log_event_list& operator<<(bool value) { 159 | int retval = android_log_write_int32(ctx, value ? 1 : 0); 160 | if (retval < 0) ret = retval; 161 | return *this; 162 | } 163 | 164 | android_log_event_list& operator<<(int64_t value) { 165 | int retval = android_log_write_int64(ctx, value); 166 | if (retval < 0) ret = retval; 167 | return *this; 168 | } 169 | 170 | android_log_event_list& operator<<(uint64_t value) { 171 | int retval = android_log_write_int64(ctx, static_cast(value)); 172 | if (retval < 0) ret = retval; 173 | return *this; 174 | } 175 | 176 | android_log_event_list& operator<<(const char* value) { 177 | int retval = android_log_write_string8(ctx, value); 178 | if (retval < 0) ret = retval; 179 | return *this; 180 | } 181 | 182 | android_log_event_list& operator<<(const std::string& value) { 183 | int retval = 184 | android_log_write_string8_len(ctx, value.data(), value.length()); 185 | if (retval < 0) ret = retval; 186 | return *this; 187 | } 188 | 189 | android_log_event_list& operator<<(float value) { 190 | int retval = android_log_write_float32(ctx, value); 191 | if (retval < 0) ret = retval; 192 | return *this; 193 | } 194 | 195 | int write(log_id_t id = LOG_ID_EVENTS) { 196 | /* facilitate -EBUSY retry */ 197 | if ((ret == -EBUSY) || (ret > 0)) ret = 0; 198 | int retval = android_log_write_list(ctx, id); 199 | /* existing errors trump transmission errors */ 200 | if (!ret) ret = retval; 201 | return ret; 202 | } 203 | 204 | int operator<<(log_id_t id) { 205 | write(id); 206 | android_log_destroy(&ctx); 207 | return ret; 208 | } 209 | 210 | /* 211 | * Append methods removes any integer promotion 212 | * confusion, and adds access to string with length. 213 | * Append methods are also added for all types for 214 | * convenience. 215 | */ 216 | 217 | bool AppendInt(int32_t value) { 218 | int retval = android_log_write_int32(ctx, value); 219 | if (retval < 0) ret = retval; 220 | return ret >= 0; 221 | } 222 | 223 | bool AppendLong(int64_t value) { 224 | int retval = android_log_write_int64(ctx, value); 225 | if (retval < 0) ret = retval; 226 | return ret >= 0; 227 | } 228 | 229 | bool AppendString(const char* value) { 230 | int retval = android_log_write_string8(ctx, value); 231 | if (retval < 0) ret = retval; 232 | return ret >= 0; 233 | } 234 | 235 | bool AppendString(const char* value, size_t len) { 236 | int retval = android_log_write_string8_len(ctx, value, len); 237 | if (retval < 0) ret = retval; 238 | return ret >= 0; 239 | } 240 | 241 | bool AppendString(const std::string& value) { 242 | int retval = 243 | android_log_write_string8_len(ctx, value.data(), value.length()); 244 | if (retval < 0) ret = retval; 245 | return ret; 246 | } 247 | 248 | bool Append(const std::string& value) { 249 | int retval = 250 | android_log_write_string8_len(ctx, value.data(), value.length()); 251 | if (retval < 0) ret = retval; 252 | return ret; 253 | } 254 | 255 | bool AppendFloat(float value) { 256 | int retval = android_log_write_float32(ctx, value); 257 | if (retval < 0) ret = retval; 258 | return ret >= 0; 259 | } 260 | 261 | template 262 | bool Append(Tvalue value) { 263 | *this << value; 264 | return ret >= 0; 265 | } 266 | 267 | bool Append(const char* value, size_t len) { 268 | int retval = android_log_write_string8_len(ctx, value, len); 269 | if (retval < 0) ret = retval; 270 | return ret >= 0; 271 | } 272 | }; 273 | } 274 | #endif 275 | 276 | #ifdef __cplusplus 277 | } 278 | #endif 279 | -------------------------------------------------------------------------------- /shim_files/liblog/include/log/log_id.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | /* 26 | * log_id_t helpers 27 | */ 28 | log_id_t android_name_to_log_id(const char* logName); 29 | const char* android_log_id_to_name(log_id_t log_id); 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | -------------------------------------------------------------------------------- /shim_files/liblog/include/log/log_main.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | __BEGIN_DECLS 26 | 27 | /* 28 | * Normally we strip the effects of ALOGV (VERBOSE messages), 29 | * LOG_FATAL and LOG_FATAL_IF (FATAL assert messages) from the 30 | * release builds be defining NDEBUG. You can modify this (for 31 | * example with "#define LOG_NDEBUG 0" at the top of your source 32 | * file) to change that behavior. 33 | */ 34 | 35 | #ifndef LOG_NDEBUG 36 | #ifdef NDEBUG 37 | #define LOG_NDEBUG 1 38 | #else 39 | #define LOG_NDEBUG 0 40 | #endif 41 | #endif 42 | 43 | /* --------------------------------------------------------------------- */ 44 | 45 | /* 46 | * This file uses ", ## __VA_ARGS__" zero-argument token pasting to 47 | * work around issues with debug-only syntax errors in assertions 48 | * that are missing format strings. See commit 49 | * 19299904343daf191267564fe32e6cd5c165cd42 50 | */ 51 | #if defined(__clang__) 52 | #pragma clang diagnostic push 53 | #pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" 54 | #endif 55 | 56 | /* 57 | * Use __VA_ARGS__ if running a static analyzer, 58 | * to avoid warnings of unused variables in __VA_ARGS__. 59 | * Use constexpr function in C++ mode, so these macros can be used 60 | * in other constexpr functions without warning. 61 | */ 62 | #ifdef __clang_analyzer__ 63 | #ifdef __cplusplus 64 | extern "C++" { 65 | template 66 | constexpr int __fake_use_va_args(Ts...) { 67 | return 0; 68 | } 69 | } 70 | #else 71 | extern int __fake_use_va_args(int, ...); 72 | #endif /* __cplusplus */ 73 | #define __FAKE_USE_VA_ARGS(...) ((void)__fake_use_va_args(0, ##__VA_ARGS__)) 74 | #else 75 | #define __FAKE_USE_VA_ARGS(...) ((void)(0)) 76 | #endif /* __clang_analyzer__ */ 77 | 78 | #ifndef __predict_false 79 | #define __predict_false(exp) __builtin_expect((exp) != 0, 0) 80 | #endif 81 | 82 | #define android_writeLog(prio, tag, text) __android_log_write(prio, tag, text) 83 | 84 | #define android_printLog(prio, tag, ...) \ 85 | __android_log_print(prio, tag, __VA_ARGS__) 86 | 87 | #define android_vprintLog(prio, cond, tag, ...) \ 88 | __android_log_vprint(prio, tag, __VA_ARGS__) 89 | 90 | /* 91 | * Log macro that allows you to specify a number for the priority. 92 | */ 93 | #ifndef LOG_PRI 94 | #define LOG_PRI(priority, tag, ...) android_printLog(priority, tag, __VA_ARGS__) 95 | #endif 96 | 97 | /* 98 | * Log macro that allows you to pass in a varargs ("args" is a va_list). 99 | */ 100 | #ifndef LOG_PRI_VA 101 | #define LOG_PRI_VA(priority, tag, fmt, args) \ 102 | android_vprintLog(priority, NULL, tag, fmt, args) 103 | #endif 104 | 105 | /* --------------------------------------------------------------------- */ 106 | 107 | /* XXX Macros to work around syntax errors in places where format string 108 | * arg is not passed to ALOG_ASSERT, LOG_ALWAYS_FATAL or LOG_ALWAYS_FATAL_IF 109 | * (happens only in debug builds). 110 | */ 111 | 112 | /* Returns 2nd arg. Used to substitute default value if caller's vararg list 113 | * is empty. 114 | */ 115 | #define __android_second(dummy, second, ...) second 116 | 117 | /* If passed multiple args, returns ',' followed by all but 1st arg, otherwise 118 | * returns nothing. 119 | */ 120 | #define __android_rest(first, ...) , ##__VA_ARGS__ 121 | 122 | #define android_printAssert(cond, tag, ...) \ 123 | __android_log_assert(cond, tag, \ 124 | __android_second(0, ##__VA_ARGS__, NULL) \ 125 | __android_rest(__VA_ARGS__)) 126 | 127 | /* 128 | * Log a fatal error. If the given condition fails, this stops program 129 | * execution like a normal assertion, but also generating the given message. 130 | * It is NOT stripped from release builds. Note that the condition test 131 | * is -inverted- from the normal assert() semantics. 132 | */ 133 | #ifndef LOG_ALWAYS_FATAL_IF 134 | #define LOG_ALWAYS_FATAL_IF(cond, ...) \ 135 | ((__predict_false(cond)) ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), \ 136 | ((void)android_printAssert(#cond, LOG_TAG, ##__VA_ARGS__))) \ 137 | : ((void)0)) 138 | #endif 139 | 140 | #ifndef LOG_ALWAYS_FATAL 141 | #define LOG_ALWAYS_FATAL(...) \ 142 | (((void)android_printAssert(NULL, LOG_TAG, ##__VA_ARGS__))) 143 | #endif 144 | 145 | /* 146 | * Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that 147 | * are stripped out of release builds. 148 | */ 149 | 150 | #if LOG_NDEBUG 151 | 152 | #ifndef LOG_FATAL_IF 153 | #define LOG_FATAL_IF(cond, ...) __FAKE_USE_VA_ARGS(__VA_ARGS__) 154 | #endif 155 | #ifndef LOG_FATAL 156 | #define LOG_FATAL(...) __FAKE_USE_VA_ARGS(__VA_ARGS__) 157 | #endif 158 | 159 | #else 160 | 161 | #ifndef LOG_FATAL_IF 162 | #define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ##__VA_ARGS__) 163 | #endif 164 | #ifndef LOG_FATAL 165 | #define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__) 166 | #endif 167 | 168 | #endif 169 | 170 | /* 171 | * Assertion that generates a log message when the assertion fails. 172 | * Stripped out of release builds. Uses the current LOG_TAG. 173 | */ 174 | #ifndef ALOG_ASSERT 175 | #define ALOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ##__VA_ARGS__) 176 | #endif 177 | 178 | /* --------------------------------------------------------------------- */ 179 | 180 | /* 181 | * C/C++ logging functions. See the logging documentation for API details. 182 | * 183 | * We'd like these to be available from C code (in case we import some from 184 | * somewhere), so this has a C interface. 185 | * 186 | * The output will be correct when the log file is shared between multiple 187 | * threads and/or multiple processes so long as the operating system 188 | * supports O_APPEND. These calls have mutex-protected data structures 189 | * and so are NOT reentrant. Do not use LOG in a signal handler. 190 | */ 191 | 192 | /* --------------------------------------------------------------------- */ 193 | 194 | /* 195 | * Simplified macro to send a verbose log message using the current LOG_TAG. 196 | */ 197 | #ifndef ALOGV 198 | #define __ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) 199 | #if LOG_NDEBUG 200 | #define ALOGV(...) \ 201 | do { \ 202 | __FAKE_USE_VA_ARGS(__VA_ARGS__); \ 203 | if (false) { \ 204 | __ALOGV(__VA_ARGS__); \ 205 | } \ 206 | } while (false) 207 | #else 208 | #define ALOGV(...) __ALOGV(__VA_ARGS__) 209 | #endif 210 | #endif 211 | 212 | #ifndef ALOGV_IF 213 | #if LOG_NDEBUG 214 | #define ALOGV_IF(cond, ...) __FAKE_USE_VA_ARGS(__VA_ARGS__) 215 | #else 216 | #define ALOGV_IF(cond, ...) \ 217 | ((__predict_false(cond)) \ 218 | ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), (void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \ 219 | : ((void)0)) 220 | #endif 221 | #endif 222 | 223 | /* 224 | * Simplified macro to send a debug log message using the current LOG_TAG. 225 | */ 226 | #ifndef ALOGD 227 | #define ALOGD(...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) 228 | #endif 229 | 230 | #ifndef ALOGD_IF 231 | #define ALOGD_IF(cond, ...) \ 232 | ((__predict_false(cond)) \ 233 | ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), (void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \ 234 | : ((void)0)) 235 | #endif 236 | 237 | /* 238 | * Simplified macro to send an info log message using the current LOG_TAG. 239 | */ 240 | #ifndef ALOGI 241 | #define ALOGI(...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) 242 | #endif 243 | 244 | #ifndef ALOGI_IF 245 | #define ALOGI_IF(cond, ...) \ 246 | ((__predict_false(cond)) \ 247 | ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), (void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \ 248 | : ((void)0)) 249 | #endif 250 | 251 | /* 252 | * Simplified macro to send a warning log message using the current LOG_TAG. 253 | */ 254 | #ifndef ALOGW 255 | #define ALOGW(...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) 256 | #endif 257 | 258 | #ifndef ALOGW_IF 259 | #define ALOGW_IF(cond, ...) \ 260 | ((__predict_false(cond)) \ 261 | ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), (void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) \ 262 | : ((void)0)) 263 | #endif 264 | 265 | /* 266 | * Simplified macro to send an error log message using the current LOG_TAG. 267 | */ 268 | #ifndef ALOGE 269 | #define ALOGE(...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) 270 | #endif 271 | 272 | #ifndef ALOGE_IF 273 | #define ALOGE_IF(cond, ...) \ 274 | ((__predict_false(cond)) \ 275 | ? (__FAKE_USE_VA_ARGS(__VA_ARGS__), (void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) \ 276 | : ((void)0)) 277 | #endif 278 | 279 | /* --------------------------------------------------------------------- */ 280 | 281 | /* 282 | * Conditional based on whether the current LOG_TAG is enabled at 283 | * verbose priority. 284 | */ 285 | #ifndef IF_ALOGV 286 | #if LOG_NDEBUG 287 | #define IF_ALOGV() if (false) 288 | #else 289 | #define IF_ALOGV() IF_ALOG(LOG_VERBOSE, LOG_TAG) 290 | #endif 291 | #endif 292 | 293 | /* 294 | * Conditional based on whether the current LOG_TAG is enabled at 295 | * debug priority. 296 | */ 297 | #ifndef IF_ALOGD 298 | #define IF_ALOGD() IF_ALOG(LOG_DEBUG, LOG_TAG) 299 | #endif 300 | 301 | /* 302 | * Conditional based on whether the current LOG_TAG is enabled at 303 | * info priority. 304 | */ 305 | #ifndef IF_ALOGI 306 | #define IF_ALOGI() IF_ALOG(LOG_INFO, LOG_TAG) 307 | #endif 308 | 309 | /* 310 | * Conditional based on whether the current LOG_TAG is enabled at 311 | * warn priority. 312 | */ 313 | #ifndef IF_ALOGW 314 | #define IF_ALOGW() IF_ALOG(LOG_WARN, LOG_TAG) 315 | #endif 316 | 317 | /* 318 | * Conditional based on whether the current LOG_TAG is enabled at 319 | * error priority. 320 | */ 321 | #ifndef IF_ALOGE 322 | #define IF_ALOGE() IF_ALOG(LOG_ERROR, LOG_TAG) 323 | #endif 324 | 325 | /* --------------------------------------------------------------------- */ 326 | 327 | /* 328 | * Basic log message macro. 329 | * 330 | * Example: 331 | * ALOG(LOG_WARN, NULL, "Failed with error %d", errno); 332 | * 333 | * The second argument may be NULL or "" to indicate the "global" tag. 334 | */ 335 | #ifndef ALOG 336 | #define ALOG(priority, tag, ...) LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__) 337 | #endif 338 | 339 | /* 340 | * Conditional given a desired logging priority and tag. 341 | */ 342 | #ifndef IF_ALOG 343 | #define IF_ALOG(priority, tag) if (android_testLog(ANDROID_##priority, tag)) 344 | #endif 345 | 346 | /* --------------------------------------------------------------------- */ 347 | 348 | /* 349 | * IF_ALOG uses android_testLog, but IF_ALOG can be overridden. 350 | * android_testLog will remain constant in its purpose as a wrapper 351 | * for Android logging filter policy, and can be subject to 352 | * change. It can be reused by the developers that override 353 | * IF_ALOG as a convenient means to reimplement their policy 354 | * over Android. 355 | */ 356 | 357 | /* 358 | * Use the per-tag properties "log.tag." to generate a runtime 359 | * result of non-zero to expose a log. prio is ANDROID_LOG_VERBOSE to 360 | * ANDROID_LOG_FATAL. default_prio if no property. Undefined behavior if 361 | * any other value. 362 | */ 363 | int __android_log_is_loggable(int prio, const char* tag, int default_prio); 364 | int __android_log_is_loggable_len(int prio, const char* tag, size_t len, int default_prio); 365 | 366 | #if LOG_NDEBUG /* Production */ 367 | #define android_testLog(prio, tag) \ 368 | (__android_log_is_loggable_len(prio, tag, (tag) ? strlen(tag) : 0, ANDROID_LOG_DEBUG) != 0) 369 | #else 370 | #define android_testLog(prio, tag) \ 371 | (__android_log_is_loggable_len(prio, tag, (tag) ? strlen(tag) : 0, ANDROID_LOG_VERBOSE) != 0) 372 | #endif 373 | 374 | #if defined(__clang__) 375 | #pragma clang diagnostic pop 376 | #endif 377 | 378 | __END_DECLS 379 | -------------------------------------------------------------------------------- /shim_files/liblog/include/log/log_properties.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | /* Returns `1` if the device is debuggable or `0` if not. */ 24 | int __android_log_is_debuggable(); 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | -------------------------------------------------------------------------------- /shim_files/liblog/include/log/log_radio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | /* 22 | * Normally we strip the effects of ALOGV (VERBOSE messages), 23 | * LOG_FATAL and LOG_FATAL_IF (FATAL assert messages) from the 24 | * release builds be defining NDEBUG. You can modify this (for 25 | * example with "#define LOG_NDEBUG 0" at the top of your source 26 | * file) to change that behavior. 27 | */ 28 | 29 | #ifndef LOG_NDEBUG 30 | #ifdef NDEBUG 31 | #define LOG_NDEBUG 1 32 | #else 33 | #define LOG_NDEBUG 0 34 | #endif 35 | #endif 36 | 37 | /* --------------------------------------------------------------------- */ 38 | 39 | #ifndef __predict_false 40 | #define __predict_false(exp) __builtin_expect((exp) != 0, 0) 41 | #endif 42 | 43 | /* 44 | * Simplified macro to send a verbose radio log message using current LOG_TAG. 45 | */ 46 | #ifndef RLOGV 47 | #define __RLOGV(...) \ 48 | ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, \ 49 | __VA_ARGS__)) 50 | #if LOG_NDEBUG 51 | #define RLOGV(...) \ 52 | do { \ 53 | if (0) { \ 54 | __RLOGV(__VA_ARGS__); \ 55 | } \ 56 | } while (0) 57 | #else 58 | #define RLOGV(...) __RLOGV(__VA_ARGS__) 59 | #endif 60 | #endif 61 | 62 | #ifndef RLOGV_IF 63 | #if LOG_NDEBUG 64 | #define RLOGV_IF(cond, ...) ((void)0) 65 | #else 66 | #define RLOGV_IF(cond, ...) \ 67 | ((__predict_false(cond)) \ 68 | ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, \ 69 | LOG_TAG, __VA_ARGS__)) \ 70 | : (void)0) 71 | #endif 72 | #endif 73 | 74 | /* 75 | * Simplified macro to send a debug radio log message using current LOG_TAG. 76 | */ 77 | #ifndef RLOGD 78 | #define RLOGD(...) \ 79 | ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, \ 80 | __VA_ARGS__)) 81 | #endif 82 | 83 | #ifndef RLOGD_IF 84 | #define RLOGD_IF(cond, ...) \ 85 | ((__predict_false(cond)) \ 86 | ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, \ 87 | LOG_TAG, __VA_ARGS__)) \ 88 | : (void)0) 89 | #endif 90 | 91 | /* 92 | * Simplified macro to send an info radio log message using current LOG_TAG. 93 | */ 94 | #ifndef RLOGI 95 | #define RLOGI(...) \ 96 | ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, \ 97 | __VA_ARGS__)) 98 | #endif 99 | 100 | #ifndef RLOGI_IF 101 | #define RLOGI_IF(cond, ...) \ 102 | ((__predict_false(cond)) \ 103 | ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, \ 104 | LOG_TAG, __VA_ARGS__)) \ 105 | : (void)0) 106 | #endif 107 | 108 | /* 109 | * Simplified macro to send a warning radio log message using current LOG_TAG. 110 | */ 111 | #ifndef RLOGW 112 | #define RLOGW(...) \ 113 | ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, \ 114 | __VA_ARGS__)) 115 | #endif 116 | 117 | #ifndef RLOGW_IF 118 | #define RLOGW_IF(cond, ...) \ 119 | ((__predict_false(cond)) \ 120 | ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, \ 121 | LOG_TAG, __VA_ARGS__)) \ 122 | : (void)0) 123 | #endif 124 | 125 | /* 126 | * Simplified macro to send an error radio log message using current LOG_TAG. 127 | */ 128 | #ifndef RLOGE 129 | #define RLOGE(...) \ 130 | ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, \ 131 | __VA_ARGS__)) 132 | #endif 133 | 134 | #ifndef RLOGE_IF 135 | #define RLOGE_IF(cond, ...) \ 136 | ((__predict_false(cond)) \ 137 | ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, \ 138 | LOG_TAG, __VA_ARGS__)) \ 139 | : (void)0) 140 | #endif 141 | -------------------------------------------------------------------------------- /shim_files/liblog/include/log/log_read.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | #define ANDROID_LOG_WRAP_DEFAULT_TIMEOUT 7200 /* 2 hour default */ 30 | 31 | /* 32 | * Native log reading interface section. See logcat for sample code. 33 | * 34 | * The preferred API is an exec of logcat. Likely uses of this interface 35 | * are if native code suffers from exec or filtration being too costly, 36 | * access to raw information, or parsing is an issue. 37 | */ 38 | 39 | struct logger_entry { 40 | uint16_t len; /* length of the payload */ 41 | uint16_t hdr_size; /* sizeof(struct logger_entry) */ 42 | int32_t pid; /* generating process's pid */ 43 | uint32_t tid; /* generating process's tid */ 44 | uint32_t sec; /* seconds since Epoch */ 45 | uint32_t nsec; /* nanoseconds */ 46 | uint32_t lid; /* log id of the payload, bottom 4 bits currently */ 47 | uint32_t uid; /* generating process's uid */ 48 | }; 49 | 50 | /* 51 | * The maximum size of a log entry which can be read. 52 | * An attempt to read less than this amount may result 53 | * in read() returning EINVAL. 54 | */ 55 | #define LOGGER_ENTRY_MAX_LEN (5 * 1024) 56 | 57 | struct log_msg { 58 | union { 59 | unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1]; 60 | struct logger_entry entry; 61 | } __attribute__((aligned(4))); 62 | #ifdef __cplusplus 63 | uint64_t nsec() const { 64 | return static_cast(entry.sec) * NS_PER_SEC + entry.nsec; 65 | } 66 | log_id_t id() { 67 | return static_cast(entry.lid); 68 | } 69 | char* msg() { 70 | unsigned short hdr_size = entry.hdr_size; 71 | if (hdr_size >= sizeof(struct log_msg) - sizeof(entry)) { 72 | return nullptr; 73 | } 74 | return reinterpret_cast(buf) + hdr_size; 75 | } 76 | unsigned int len() { return entry.hdr_size + entry.len; } 77 | #endif 78 | }; 79 | 80 | struct logger; 81 | 82 | log_id_t android_logger_get_id(struct logger* logger); 83 | 84 | /* Clears the given log buffer. */ 85 | int android_logger_clear(struct logger* logger); 86 | /* Return the allotted size for the given log buffer. */ 87 | long android_logger_get_log_size(struct logger* logger); 88 | /* Set the allotted size for the given log buffer. */ 89 | int android_logger_set_log_size(struct logger* logger, unsigned long size); 90 | /* Return the actual, uncompressed size that can be read from the given log buffer. */ 91 | long android_logger_get_log_readable_size(struct logger* logger); 92 | /* Return the actual, compressed size that the given log buffer is consuming. */ 93 | long android_logger_get_log_consumed_size(struct logger* logger); 94 | /* Deprecated. Always returns '4' regardless of input. */ 95 | int android_logger_get_log_version(struct logger* logger); 96 | 97 | struct logger_list; 98 | 99 | ssize_t android_logger_get_statistics(struct logger_list* logger_list, 100 | char* buf, size_t len); 101 | ssize_t android_logger_get_prune_list(struct logger_list* logger_list, 102 | char* buf, size_t len); 103 | int android_logger_set_prune_list(struct logger_list* logger_list, const char* buf, size_t len); 104 | 105 | /* The below values are used for the `mode` argument of the below functions. */ 106 | /* Note that 0x00000003 were previously used and should be considered reserved. */ 107 | #define ANDROID_LOG_NONBLOCK 0x00000800 108 | #define ANDROID_LOG_WRAP 0x40000000 /* Block until buffer about to wrap */ 109 | #define ANDROID_LOG_PSTORE 0x80000000 110 | 111 | struct logger_list* android_logger_list_alloc(int mode, unsigned int tail, 112 | pid_t pid); 113 | struct logger_list* android_logger_list_alloc_time(int mode, log_time start, 114 | pid_t pid); 115 | void android_logger_list_free(struct logger_list* logger_list); 116 | /* In the purest sense, the following two are orthogonal interfaces */ 117 | int android_logger_list_read(struct logger_list* logger_list, 118 | struct log_msg* log_msg); 119 | 120 | /* Multiple log_id_t opens */ 121 | struct logger* android_logger_open(struct logger_list* logger_list, log_id_t id); 122 | /* Single log_id_t open */ 123 | struct logger_list* android_logger_list_open(log_id_t id, int mode, 124 | unsigned int tail, pid_t pid); 125 | #define android_logger_list_close android_logger_list_free 126 | 127 | #ifdef __cplusplus 128 | } 129 | #endif 130 | -------------------------------------------------------------------------------- /shim_files/liblog/include/log/log_safetynet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | #define android_errorWriteLog(tag, subTag) \ 26 | __android_log_error_write(tag, subTag, -1, NULL, 0) 27 | 28 | #define android_errorWriteWithInfoLog(tag, subTag, uid, data, dataLen) \ 29 | __android_log_error_write(tag, subTag, uid, data, dataLen) 30 | 31 | int __android_log_error_write(int tag, const char* subTag, int32_t uid, 32 | const char* data, uint32_t dataLen); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | -------------------------------------------------------------------------------- /shim_files/liblog/include/log/log_system.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | /* 22 | * Normally we strip the effects of ALOGV (VERBOSE messages), 23 | * LOG_FATAL and LOG_FATAL_IF (FATAL assert messages) from the 24 | * release builds be defining NDEBUG. You can modify this (for 25 | * example with "#define LOG_NDEBUG 0" at the top of your source 26 | * file) to change that behavior. 27 | */ 28 | 29 | #ifndef LOG_NDEBUG 30 | #ifdef NDEBUG 31 | #define LOG_NDEBUG 1 32 | #else 33 | #define LOG_NDEBUG 0 34 | #endif 35 | #endif 36 | 37 | #ifndef __predict_false 38 | #define __predict_false(exp) __builtin_expect((exp) != 0, 0) 39 | #endif 40 | 41 | /* 42 | * Simplified macro to send a verbose system log message using current LOG_TAG. 43 | */ 44 | #ifndef SLOGV 45 | #define __SLOGV(...) \ 46 | ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, \ 47 | __VA_ARGS__)) 48 | #if LOG_NDEBUG 49 | #define SLOGV(...) \ 50 | do { \ 51 | if (0) { \ 52 | __SLOGV(__VA_ARGS__); \ 53 | } \ 54 | } while (0) 55 | #else 56 | #define SLOGV(...) __SLOGV(__VA_ARGS__) 57 | #endif 58 | #endif 59 | 60 | #ifndef SLOGV_IF 61 | #if LOG_NDEBUG 62 | #define SLOGV_IF(cond, ...) ((void)0) 63 | #else 64 | #define SLOGV_IF(cond, ...) \ 65 | ((__predict_false(cond)) \ 66 | ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, \ 67 | LOG_TAG, __VA_ARGS__)) \ 68 | : (void)0) 69 | #endif 70 | #endif 71 | 72 | /* 73 | * Simplified macro to send a debug system log message using current LOG_TAG. 74 | */ 75 | #ifndef SLOGD 76 | #define SLOGD(...) \ 77 | ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, \ 78 | __VA_ARGS__)) 79 | #endif 80 | 81 | #ifndef SLOGD_IF 82 | #define SLOGD_IF(cond, ...) \ 83 | ((__predict_false(cond)) \ 84 | ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, \ 85 | LOG_TAG, __VA_ARGS__)) \ 86 | : (void)0) 87 | #endif 88 | 89 | /* 90 | * Simplified macro to send an info system log message using current LOG_TAG. 91 | */ 92 | #ifndef SLOGI 93 | #define SLOGI(...) \ 94 | ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, \ 95 | __VA_ARGS__)) 96 | #endif 97 | 98 | #ifndef SLOGI_IF 99 | #define SLOGI_IF(cond, ...) \ 100 | ((__predict_false(cond)) \ 101 | ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, \ 102 | LOG_TAG, __VA_ARGS__)) \ 103 | : (void)0) 104 | #endif 105 | 106 | /* 107 | * Simplified macro to send a warning system log message using current LOG_TAG. 108 | */ 109 | #ifndef SLOGW 110 | #define SLOGW(...) \ 111 | ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, \ 112 | __VA_ARGS__)) 113 | #endif 114 | 115 | #ifndef SLOGW_IF 116 | #define SLOGW_IF(cond, ...) \ 117 | ((__predict_false(cond)) \ 118 | ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, \ 119 | LOG_TAG, __VA_ARGS__)) \ 120 | : (void)0) 121 | #endif 122 | 123 | /* 124 | * Simplified macro to send an error system log message using current LOG_TAG. 125 | */ 126 | #ifndef SLOGE 127 | #define SLOGE(...) \ 128 | ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, \ 129 | __VA_ARGS__)) 130 | #endif 131 | 132 | #ifndef SLOGE_IF 133 | #define SLOGE_IF(cond, ...) \ 134 | ((__predict_false(cond)) \ 135 | ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, \ 136 | LOG_TAG, __VA_ARGS__)) \ 137 | : (void)0) 138 | #endif 139 | -------------------------------------------------------------------------------- /shim_files/liblog/include/log/log_time.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | /* struct log_time is a wire-format variant of struct timespec */ 23 | #define NS_PER_SEC 1000000000ULL 24 | #define US_PER_SEC 1000000ULL 25 | #define MS_PER_SEC 1000ULL 26 | 27 | #define LOG_TIME_SEC(t) ((t)->tv_sec) 28 | /* next power of two after NS_PER_SEC */ 29 | #define LOG_TIME_NSEC(t) ((t)->tv_nsec & (UINT32_MAX >> 2)) 30 | 31 | #ifdef __cplusplus 32 | 33 | extern "C" { 34 | 35 | struct log_time { 36 | public: 37 | uint32_t tv_sec = 0; /* good to Feb 5 2106 */ 38 | uint32_t tv_nsec = 0; 39 | 40 | static constexpr timespec EPOCH = {0, 0}; 41 | 42 | log_time() {} 43 | explicit log_time(const timespec& T) 44 | : tv_sec(static_cast(T.tv_sec)), tv_nsec(static_cast(T.tv_nsec)) {} 45 | explicit log_time(uint32_t sec, uint32_t nsec = 0) 46 | : tv_sec(sec), tv_nsec(nsec) { 47 | } 48 | #ifdef __linux__ 49 | explicit log_time(clockid_t id) { 50 | timespec T; 51 | clock_gettime(id, &T); 52 | tv_sec = static_cast(T.tv_sec); 53 | tv_nsec = static_cast(T.tv_nsec); 54 | } 55 | #endif 56 | /* timespec */ 57 | bool operator==(const timespec& T) const { 58 | return (tv_sec == static_cast(T.tv_sec)) && 59 | (tv_nsec == static_cast(T.tv_nsec)); 60 | } 61 | bool operator!=(const timespec& T) const { 62 | return !(*this == T); 63 | } 64 | bool operator<(const timespec& T) const { 65 | return (tv_sec < static_cast(T.tv_sec)) || 66 | ((tv_sec == static_cast(T.tv_sec)) && 67 | (tv_nsec < static_cast(T.tv_nsec))); 68 | } 69 | bool operator>=(const timespec& T) const { 70 | return !(*this < T); 71 | } 72 | bool operator>(const timespec& T) const { 73 | return (tv_sec > static_cast(T.tv_sec)) || 74 | ((tv_sec == static_cast(T.tv_sec)) && 75 | (tv_nsec > static_cast(T.tv_nsec))); 76 | } 77 | bool operator<=(const timespec& T) const { 78 | return !(*this > T); 79 | } 80 | 81 | /* log_time */ 82 | bool operator==(const log_time& T) const { 83 | return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec); 84 | } 85 | bool operator!=(const log_time& T) const { 86 | return !(*this == T); 87 | } 88 | bool operator<(const log_time& T) const { 89 | return (tv_sec < T.tv_sec) || 90 | ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec)); 91 | } 92 | bool operator>=(const log_time& T) const { 93 | return !(*this < T); 94 | } 95 | bool operator>(const log_time& T) const { 96 | return (tv_sec > T.tv_sec) || 97 | ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec)); 98 | } 99 | bool operator<=(const log_time& T) const { 100 | return !(*this > T); 101 | } 102 | 103 | log_time operator-=(const log_time& T) { 104 | // No concept of negative time, clamp to EPOCH 105 | if (*this <= T) { 106 | return *this = log_time(EPOCH); 107 | } 108 | 109 | if (this->tv_nsec < T.tv_nsec) { 110 | --this->tv_sec; 111 | this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec; 112 | } else { 113 | this->tv_nsec -= T.tv_nsec; 114 | } 115 | this->tv_sec -= T.tv_sec; 116 | 117 | return *this; 118 | } 119 | log_time operator-(const log_time& T) const { 120 | log_time local(*this); 121 | return local -= T; 122 | } 123 | log_time operator+=(const log_time& T) { 124 | this->tv_nsec += T.tv_nsec; 125 | if (this->tv_nsec >= NS_PER_SEC) { 126 | this->tv_nsec -= NS_PER_SEC; 127 | ++this->tv_sec; 128 | } 129 | this->tv_sec += T.tv_sec; 130 | 131 | return *this; 132 | } 133 | log_time operator+(const log_time& T) const { 134 | log_time local(*this); 135 | return local += T; 136 | } 137 | 138 | uint64_t nsec() const { 139 | return static_cast(tv_sec) * NS_PER_SEC + tv_nsec; 140 | } 141 | uint64_t usec() const { 142 | return static_cast(tv_sec) * US_PER_SEC + 143 | tv_nsec / (NS_PER_SEC / US_PER_SEC); 144 | } 145 | uint64_t msec() const { 146 | return static_cast(tv_sec) * MS_PER_SEC + 147 | tv_nsec / (NS_PER_SEC / MS_PER_SEC); 148 | } 149 | 150 | /* Add %#q for the fraction of a second to the standard library functions */ 151 | char* strptime(const char* s, const char* format); 152 | } __attribute__((__packed__)); 153 | } 154 | 155 | #else /* __cplusplus */ 156 | 157 | typedef struct log_time { 158 | uint32_t tv_sec; 159 | uint32_t tv_nsec; 160 | } __attribute__((__packed__)) log_time; 161 | 162 | #endif /* __cplusplus */ 163 | -------------------------------------------------------------------------------- /shim_files/liblog/include/log/logprint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2006 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | typedef enum { 31 | /* Verbs */ 32 | FORMAT_OFF = 0, 33 | FORMAT_BRIEF, 34 | FORMAT_PROCESS, 35 | FORMAT_TAG, 36 | FORMAT_THREAD, 37 | FORMAT_RAW, 38 | FORMAT_TIME, 39 | FORMAT_THREADTIME, 40 | FORMAT_LONG, 41 | /* Adverbs. The following are modifiers to above format verbs */ 42 | FORMAT_MODIFIER_COLOR, /* converts priority to color */ 43 | FORMAT_MODIFIER_TIME_USEC, /* switches from msec to usec time precision */ 44 | FORMAT_MODIFIER_PRINTABLE, /* converts non-printable to printable escapes */ 45 | FORMAT_MODIFIER_YEAR, /* Adds year to date */ 46 | FORMAT_MODIFIER_ZONE, /* Adds zone to date, + UTC */ 47 | FORMAT_MODIFIER_EPOCH, /* Print time as seconds since Jan 1 1970 */ 48 | FORMAT_MODIFIER_MONOTONIC, /* Print cpu time as seconds since start */ 49 | FORMAT_MODIFIER_UID, /* Adds uid */ 50 | FORMAT_MODIFIER_DESCRIPT, /* Adds descriptive */ 51 | /* private, undocumented */ 52 | FORMAT_MODIFIER_TIME_NSEC, /* switches from msec to nsec time precision */ 53 | } AndroidLogPrintFormat; 54 | 55 | typedef struct AndroidLogFormat_t AndroidLogFormat; 56 | 57 | typedef struct AndroidLogEntry_t { 58 | time_t tv_sec; 59 | long tv_nsec; 60 | android_LogPriority priority; 61 | int32_t uid; 62 | int32_t pid; 63 | int32_t tid; 64 | const char* tag; 65 | size_t tagLen; 66 | size_t messageLen; 67 | const char* message; 68 | } AndroidLogEntry; 69 | 70 | AndroidLogFormat* android_log_format_new(); 71 | 72 | void android_log_format_free(AndroidLogFormat* p_format); 73 | 74 | /* currently returns 0 if format is a modifier, 1 if not */ 75 | int android_log_setPrintFormat(AndroidLogFormat* p_format, 76 | AndroidLogPrintFormat format); 77 | 78 | /** 79 | * Returns FORMAT_OFF on invalid string 80 | */ 81 | AndroidLogPrintFormat android_log_formatFromString(const char* s); 82 | 83 | /** 84 | * filterExpression: a single filter expression 85 | * eg "AT:d" 86 | * 87 | * returns 0 on success and -1 on invalid expression 88 | * 89 | * Assumes single threaded execution 90 | * 91 | */ 92 | 93 | int android_log_addFilterRule(AndroidLogFormat* p_format, 94 | const char* filterExpression); 95 | 96 | /** 97 | * filterString: a whitespace-separated set of filter expressions 98 | * eg "AT:d *:i" 99 | * 100 | * returns 0 on success and -1 on invalid expression 101 | * 102 | * Assumes single threaded execution 103 | * 104 | */ 105 | 106 | int android_log_addFilterString(AndroidLogFormat* p_format, 107 | const char* filterString); 108 | 109 | /** 110 | * returns 1 if this log line should be printed based on its priority 111 | * and tag, and 0 if it should not 112 | */ 113 | int android_log_shouldPrintLine(AndroidLogFormat* p_format, const char* tag, 114 | android_LogPriority pri); 115 | 116 | /** 117 | * Splits a wire-format buffer into an AndroidLogEntry 118 | * entry allocated by caller. Pointers will point directly into buf 119 | * 120 | * Returns 0 on success and -1 on invalid wire format (entry will be 121 | * in unspecified state) 122 | */ 123 | int android_log_processLogBuffer(struct logger_entry* buf, 124 | AndroidLogEntry* entry); 125 | 126 | /** 127 | * Like android_log_processLogBuffer, but for binary logs. 128 | * 129 | * If "map" is non-NULL, it will be used to convert the log tag number 130 | * into a string. 131 | */ 132 | int android_log_processBinaryLogBuffer(struct logger_entry* buf, 133 | AndroidLogEntry* entry, 134 | const EventTagMap* map, char* messageBuf, 135 | int messageBufLen); 136 | 137 | /** 138 | * Formats a log message into a buffer 139 | * 140 | * Uses defaultBuffer if it can, otherwise malloc()'s a new buffer 141 | * If return value != defaultBuffer, caller must call free() 142 | * Returns NULL on malloc error 143 | */ 144 | 145 | char* android_log_formatLogLine(AndroidLogFormat* p_format, char* defaultBuffer, 146 | size_t defaultBufferSize, 147 | const AndroidLogEntry* p_line, 148 | size_t* p_outLength); 149 | 150 | /** 151 | * Formats a log message into a FILE*. 152 | */ 153 | size_t android_log_printLogLine(AndroidLogFormat* p_format, FILE* fp, const AndroidLogEntry* entry); 154 | 155 | #ifdef __cplusplus 156 | } 157 | #endif 158 | -------------------------------------------------------------------------------- /shim_files/liblog/include/private/android_logger.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* This file is used to define the internal protocol for the Android Logger */ 18 | 19 | #pragma once 20 | 21 | /* Android private interfaces */ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #ifdef __cplusplus 28 | #include 29 | #endif 30 | 31 | #include 32 | #include 33 | 34 | #define LOGGER_MAGIC 'l' 35 | 36 | #if defined(__cplusplus) 37 | extern "C" { 38 | #endif 39 | 40 | /* Header Structure to pstore */ 41 | typedef struct __attribute__((__packed__)) { 42 | uint8_t magic; 43 | uint16_t len; 44 | uint16_t uid; 45 | uint16_t pid; 46 | } android_pmsg_log_header_t; 47 | 48 | /* Header Structure to logd, and second header for pstore */ 49 | typedef struct __attribute__((__packed__)) { 50 | uint8_t id; 51 | uint16_t tid; 52 | log_time realtime; 53 | } android_log_header_t; 54 | 55 | /* Event Header Structure to logd */ 56 | typedef struct __attribute__((__packed__)) { 57 | int32_t tag; // Little Endian Order 58 | } android_event_header_t; 59 | 60 | // Event payload EVENT_TYPE_LIST 61 | typedef struct __attribute__((__packed__)) { 62 | int8_t type; // EVENT_TYPE_LIST 63 | int8_t element_count; 64 | } android_event_list_t; 65 | 66 | // Event payload EVENT_TYPE_FLOAT 67 | typedef struct __attribute__((__packed__)) { 68 | int8_t type; // EVENT_TYPE_FLOAT 69 | float data; 70 | } android_event_float_t; 71 | 72 | /* Event payload EVENT_TYPE_INT */ 73 | typedef struct __attribute__((__packed__)) { 74 | int8_t type; // EVENT_TYPE_INT 75 | int32_t data; // Little Endian Order 76 | } android_event_int_t; 77 | 78 | /* Event with single EVENT_TYPE_INT */ 79 | typedef struct __attribute__((__packed__)) { 80 | android_event_header_t header; 81 | android_event_int_t payload; 82 | } android_log_event_int_t; 83 | 84 | /* Event payload EVENT_TYPE_LONG */ 85 | typedef struct __attribute__((__packed__)) { 86 | int8_t type; // EVENT_TYPE_LONG 87 | int64_t data; // Little Endian Order 88 | } android_event_long_t; 89 | 90 | /* Event with single EVENT_TYPE_LONG */ 91 | typedef struct __attribute__((__packed__)) { 92 | android_event_header_t header; 93 | android_event_long_t payload; 94 | } android_log_event_long_t; 95 | 96 | /* 97 | * Event payload EVENT_TYPE_STRING 98 | * 99 | * Danger: do not embed this structure into another structure. 100 | * This structure uses a flexible array member, and when 101 | * compiled using g++, __builtin_object_size(data, 1) returns 102 | * a bad value. This is possibly a g++ bug, or a bug due to 103 | * the fact that flexible array members are not supported 104 | * in C++. 105 | * http://stackoverflow.com/questions/4412749/are-flexible-array-members-valid-in-c 106 | */ 107 | 108 | typedef struct __attribute__((__packed__)) { 109 | int8_t type; // EVENT_TYPE_STRING; 110 | int32_t length; // Little Endian Order 111 | char data[]; 112 | } android_event_string_t; 113 | 114 | /* Event with single EVENT_TYPE_STRING */ 115 | typedef struct __attribute__((__packed__)) { 116 | android_event_header_t header; 117 | int8_t type; // EVENT_TYPE_STRING; 118 | int32_t length; // Little Endian Order 119 | char data[]; 120 | } android_log_event_string_t; 121 | 122 | #define ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE 256 /* 1MB file */ 123 | #define ANDROID_LOG_PMSG_FILE_SEQUENCE 1000 124 | 125 | ssize_t __android_log_pmsg_file_write(log_id_t logId, char prio, 126 | const char* filename, const char* buf, 127 | size_t len); 128 | 129 | #define ANDROID_LOG_ANY ANDROID_LOG_UNKNOWN 130 | 131 | /* first 5 arguments match __android_log_msg_file_write, a cast is safe */ 132 | typedef ssize_t (*__android_log_pmsg_file_read_fn)(log_id_t logId, char prio, 133 | const char* filename, 134 | const char* buf, size_t len, 135 | void* arg); 136 | 137 | ssize_t __android_log_pmsg_file_read(log_id_t logId, char prio, 138 | const char* prefix, 139 | __android_log_pmsg_file_read_fn fn, 140 | void* arg); 141 | 142 | int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len); 143 | int __android_log_security_bswrite(int32_t tag, const char* payload); 144 | int __android_log_security(); /* Device Owner is present */ 145 | 146 | /* Retrieve the composed event buffer */ 147 | int android_log_write_list_buffer(android_log_context ctx, const char** msg); 148 | 149 | #if defined(__cplusplus) 150 | } 151 | #endif 152 | -------------------------------------------------------------------------------- /shim_files/libunwindstack/Demangle.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | #include 23 | 24 | namespace unwindstack { 25 | 26 | std::string DemangleNameIfNeeded(const std::string& name) { 27 | if (name.length() < 2 || name[0] != '_') { 28 | return name; 29 | } 30 | 31 | char* demangled_str = nullptr; 32 | if (name[1] == 'Z') { 33 | // Try to demangle C++ name. 34 | demangled_str = abi::__cxa_demangle(name.c_str(), nullptr, nullptr, nullptr); 35 | } 36 | 37 | if (demangled_str == nullptr) { 38 | return name; 39 | } 40 | 41 | std::string demangled_name(demangled_str); 42 | free(demangled_str); 43 | return demangled_name; 44 | } 45 | 46 | } // namespace unwindstack 47 | -------------------------------------------------------------------------------- /shim_files/libunwindstack/ThreadUnwinder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | #include "ThreadEntry.h" 36 | 37 | namespace unwindstack { 38 | 39 | static void SignalLogOnly(int, siginfo_t*, void*) { 40 | android::base::ErrnoRestorer restore; 41 | 42 | Log::AsyncSafe("pid %d, tid %d: Received a spurious thread signal\n", getpid(), 43 | static_cast(android::base::GetThreadId())); 44 | } 45 | 46 | static void SignalHandler(int, siginfo_t*, void* sigcontext) { 47 | android::base::ErrnoRestorer restore; 48 | 49 | ThreadEntry* entry = ThreadEntry::Get(android::base::GetThreadId(), false); 50 | if (!entry) { 51 | return; 52 | } 53 | 54 | entry->CopyUcontextFromSigcontext(sigcontext); 55 | 56 | // Indicate the ucontext is now valid. 57 | entry->Wake(); 58 | // Pause the thread until the unwind is complete. This avoids having 59 | // the thread run ahead causing problems. 60 | // The number indicates that we are waiting for the second Wake() call 61 | // overall which is made by the thread requesting an unwind. 62 | if (entry->Wait(WAIT_FOR_UNWIND_TO_COMPLETE)) { 63 | // Do not remove the entry here because that can result in a deadlock 64 | // if the code cannot properly send a signal to the thread under test. 65 | entry->Wake(); 66 | } 67 | // If the wait fails, the entry might have been freed, so only exit. 68 | } 69 | 70 | ThreadUnwinder::ThreadUnwinder(size_t max_frames, Maps* maps) 71 | : UnwinderFromPid(max_frames, getpid(), Regs::CurrentArch(), maps) {} 72 | 73 | ThreadUnwinder::ThreadUnwinder(size_t max_frames, Maps* maps, 74 | std::shared_ptr& process_memory) 75 | : UnwinderFromPid(max_frames, getpid(), Regs::CurrentArch(), maps, process_memory) {} 76 | 77 | ThreadUnwinder::ThreadUnwinder(size_t max_frames, const ThreadUnwinder* unwinder) 78 | : UnwinderFromPid(max_frames, getpid(), Regs::CurrentArch()) { 79 | process_memory_ = unwinder->process_memory_; 80 | maps_ = unwinder->maps_; 81 | jit_debug_ = unwinder->jit_debug_; 82 | dex_files_ = unwinder->dex_files_; 83 | initted_ = unwinder->initted_; 84 | } 85 | 86 | ThreadEntry* ThreadUnwinder::SendSignalToThread(int signal, pid_t tid) { 87 | static std::mutex action_mutex; 88 | std::lock_guard guard(action_mutex); 89 | 90 | ThreadEntry* entry = ThreadEntry::Get(tid); 91 | entry->Lock(); 92 | struct sigaction new_action = {}; 93 | new_action.sa_sigaction = SignalHandler; 94 | new_action.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; 95 | struct sigaction old_action = {}; 96 | sigemptyset(&new_action.sa_mask); 97 | if (sigaction(signal, &new_action, &old_action) != 0) { 98 | Log::AsyncSafe("sigaction failed: %s", strerror(errno)); 99 | ThreadEntry::Remove(entry); 100 | last_error_.code = ERROR_SYSTEM_CALL; 101 | return nullptr; 102 | } 103 | 104 | if (tgkill(getpid(), tid, signal) != 0) { 105 | // Do not emit an error message, this might be expected. Set the 106 | // error and let the caller decide. 107 | if (errno == ESRCH) { 108 | last_error_.code = ERROR_THREAD_DOES_NOT_EXIST; 109 | } else { 110 | last_error_.code = ERROR_SYSTEM_CALL; 111 | } 112 | 113 | sigaction(signal, &old_action, nullptr); 114 | ThreadEntry::Remove(entry); 115 | return nullptr; 116 | } 117 | 118 | // Wait for the thread to get the ucontext. The number indicates 119 | // that we are waiting for the first Wake() call made by the thread. 120 | bool wait_completed = entry->Wait(WAIT_FOR_UCONTEXT); 121 | if (wait_completed) { 122 | return entry; 123 | } 124 | 125 | if (old_action.sa_sigaction == nullptr) { 126 | // If the wait failed, it could be that the signal could not be delivered 127 | // within the timeout. Add a signal handler that's simply going to log 128 | // something so that we don't crash if the signal eventually gets 129 | // delivered. Only do this if there isn't already an action set up. 130 | struct sigaction log_action = {}; 131 | log_action.sa_sigaction = SignalLogOnly; 132 | log_action.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; 133 | sigemptyset(&log_action.sa_mask); 134 | sigaction(signal, &log_action, nullptr); 135 | } else { 136 | sigaction(signal, &old_action, nullptr); 137 | } 138 | 139 | // Check to see if the thread has disappeared. 140 | if (tgkill(getpid(), tid, 0) == -1 && errno == ESRCH) { 141 | last_error_.code = ERROR_THREAD_DOES_NOT_EXIST; 142 | } else { 143 | last_error_.code = ERROR_THREAD_TIMEOUT; 144 | } 145 | 146 | ThreadEntry::Remove(entry); 147 | 148 | return nullptr; 149 | } 150 | 151 | void ThreadUnwinder::UnwindWithSignal(int signal, pid_t tid, std::unique_ptr* initial_regs, 152 | const std::vector* initial_map_names_to_skip, 153 | const std::vector* map_suffixes_to_ignore) { 154 | ClearErrors(); 155 | if (tid == static_cast(android::base::GetThreadId())) { 156 | last_error_.code = ERROR_UNSUPPORTED; 157 | return; 158 | } 159 | 160 | if (!Init()) { 161 | return; 162 | } 163 | 164 | ThreadEntry* entry = SendSignalToThread(signal, tid); 165 | if (entry == nullptr) { 166 | return; 167 | } 168 | 169 | std::unique_ptr regs(Regs::CreateFromUcontext(Regs::CurrentArch(), entry->GetUcontext())); 170 | if (initial_regs != nullptr) { 171 | initial_regs->reset(regs->Clone()); 172 | } 173 | SetRegs(regs.get()); 174 | UnwinderFromPid::Unwind(initial_map_names_to_skip, map_suffixes_to_ignore); 175 | 176 | // Tell the signal handler to exit and release the entry. 177 | entry->Wake(); 178 | 179 | // Wait for the thread to indicate it is done with the ThreadEntry. 180 | // If this fails, the Wait command will log an error message. 181 | entry->Wait(WAIT_FOR_THREAD_TO_RESTART); 182 | 183 | ThreadEntry::Remove(entry); 184 | } 185 | 186 | } // namespace unwindstack 187 | --------------------------------------------------------------------------------