【NDK系列】Android tombstone文件分析
文件位置
data/tombstone/tombstone_xx.txt
获取tombstone文件命令:
adb shell cp /data/tombstones ./tombstones
触发时机
NDK程序在发生崩溃时,它会在路径/data/tombstones/
下产生导致程序crash的文件tombstone_xx
,记录了死亡了进程的基本信息(例如进程的进程号,线程号),死亡的地址(在哪个地址上发生了Crash),死亡时的现场是什么样的(记录了一系列的堆栈调用信息)等等。
内容示例
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'Android-x86/android_x86/x86:5.1.1/LMY48W/woshijpf04211939:eng/test-keys'
Revision: '0'
ABI: 'x86'
pid: 1019, tid: 1019, name: surfaceflinger >>> /system/bin/surfaceflinger <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4eax a6265c06 ebx b7467d88 ecx b7631a22 edx a6265c06esi 00000000 edi b6867140xcs 00000073 xds 0000007b xes 0000007b xfs 00000000 xss 0000007beip b745a639 ebp bfcfc1e8 esp bfcfc150 flags 00010282backtrace:#00 pc 00006639 /system/lib/libui.so (android::Fence::waitForever(char const*)+41)#01 pc 00034b86 /system/lib/libsurfaceflinger.so#02 pc 0003229e /system/lib/libsurfaceflinger.so#03 pc 0002cb9c /system/lib/libgui.so (android::BufferQueue::ProxyConsumerListener::onFrameAvailable(android::BufferItem const&)+652)#04 pc 000342f4 /system/lib/libgui.so (android::BufferQueueProducer::queueBuffer(int, android::IGraphicBufferProducer::QueueBufferInput const&, android::IGraphicBufferProducer::QueueBufferOutput*)+2580)#05 pc 0004eafb /system/lib/libgui.so (android::Surface::queueBuffer(ANativeWindowBuffer*, int)+411)#06 pc 0004ce06 /system/lib/libgui.so (android::Surface::hook_queueBuffer(ANativeWindow*, ANativeWindowBuffer*, int)+38)#07 pc 00014bc6 /system/lib/egl/libGLES_android.so#08 pc 00017f73 /system/lib/egl/libGLES_android.so (eglSwapBuffers+163)#09 pc 00015fdb /system/lib/libEGL.so (eglSwapBuffers+203)#10 pc 000013ea /system/lib/hw/hwcomposer.x86.so#11 pc 00034730 /system/lib/libsurfaceflinger.so#12 pc 000256d4 /system/lib/libsurfaceflinger.so#13 pc 00024bf4 /system/lib/libsurfaceflinger.so#14 pc 000236fb /system/lib/libsurfaceflinger.so#15 pc 0002338a /system/lib/libsurfaceflinger.so#16 pc 0001e0ff /system/lib/libsurfaceflinger.so#17 pc 0001d9ce /system/lib/libutils.so (android::Looper::pollInner(int)+926)#18 pc 0001db73 /system/lib/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+67)#19 pc 0001e561 /system/lib/libsurfaceflinger.so#20 pc 00022ce7 /system/lib/libsurfaceflinger.so (android::SurfaceFlinger::run()+39)#21 pc 00000ca3 /system/bin/surfaceflinger#22 pc 0001365a /system/lib/libc.so (__libc_init+106)#23 pc 00000da8 /system/bin/surfaceflingerstack:bfcfc110 00000000 bfcfc114 b6839270 bfcfc118 00000000 bfcfc11c 00000000 bfcfc120 b68394e0 bfcfc124 00000002 bfcfc128 00000002 bfcfc12c b75d8185 /system/lib/libutils.so (android::RefBase::incStrong(void const*) const+53)bfcfc130 b6839270 bfcfc134 bfcfc1e8 [stack]bfcfc138 00000002 bfcfc13c a6265c06 bfcfc140 b7467d88 /system/lib/libui.sobfcfc144 00000000 bfcfc148 b6867140 bfcfc14c b745a639 /system/lib/libui.so (android::Fence::waitForever(char const*)+41)#00 bfcfc150 b683af18 bfcfc154 bfcfc1e8 [stack]bfcfc158 00000000 bfcfc15c 00000000 bfcfc160 00000000 bfcfc164 b683af18 bfcfc168 b75ec9c4 /system/lib/libutils.sobfcfc16c b75d8285 /system/lib/libutils.so (android::RefBase::weakref_type::decWeak(void const*)+37)bfcfc170 00000000 bfcfc174 00000000 bfcfc178 00000000 bfcfc17c 00000000 bfcfc180 b7642968 /system/lib/libsurfaceflinger.sobfcfc184 bfcfc1e8 [stack]bfcfc188 b6867140 bfcfc18c b7622b87 /system/lib/libsurfaceflinger.so
构建指纹
Build fingerprint: 'Android-x86/android_x86/x86:5.1.1/LMY48W/woshijpf04211939:eng/test-keys'
典型的格式为:AOSP/[Android Version]/[Build ID]/[Build Date]
- “Android-x86”: 表示Android-x86工程
- “android_x86”: 表示Android-x86工程的分支名或者构建变体
- “x86:5.1.1”: 表示安卓版本为5.1.1, 即Lollipop。"x86"表示其针对x86架构CPU进行优化
- “LMY48W”: 表示构建号(build number),构建号可以自定义,比如某个feature、bugfix的提交号
- “woshijpf04211939:eng”: 自定义标签,比如构建者、构建目等,“eng” 可能表示使用了engineering配置
- “test-keys”: 表示此构建使用了测试key而不是正式发布的key文件
崩溃的过程和PID
pid: 1019, tid: 1019, name: surfaceflinger >>> /system/bin/surfaceflinger <<<
如果pid等于tid,那么就说明这个程序是在主线程中Crash掉的,名称的属性则表示Crash进程的名称以及在文件系统中位置。
终止信号和故障地址
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4
信息说明出现进程Crash的原因是因为程序产生了段错误的信号,访问了非法的内存空间,而访问的非法地址是0x4。
典型的内存地址访问错误:
- 野指针
- 内存泄露
- 堆栈溢出
- 初始化错误
- 类型转换错误
- 数字除0
Linux信号机制
信号机制是Linux进程间通信的一种重要方式,Linux信号一方面用于正常的进程间通信和同步,如任务控制(SIGINT,SIGTSTP,SIGKILL,SIGCONT,…);另一方面,它还负责监控系统异常及中断。当应用程序运行异常时,Linux内核将产生错误信号并通知当前进程。当前进程在接收到该错误信号后,可以有三种不同的处理方式:
- 忽略该信号。
- 捕捉该信号并执行对应的信号处理函数(信号处理程序)。
- 执行该信号的缺省操作(如SIGSEGV,其缺省操作是终止进程)。
当Linux应用程序在执行时发生严重错误,一般会导致程序崩溃。其中,Linux专门提供了一类crash信号,在程序接收到此类信号时,缺省操作是将崩溃的现场信息记录到核心文件,然后终止进程。
CPU寄存器
略
调用堆栈
backtrace:#00 pc 00006639 /system/lib/libui.so (android::Fence::waitForever(char const*)+41)#01 pc 00034b86 /system/lib/libsurfaceflinger.so#02 pc 0003229e /system/lib/libsurfaceflinger.so#03 pc 0002cb9c /system/lib/libgui.so (android::BufferQueue::ProxyConsumerListener::onFrameAvailable(android::BufferItem const&)+652)#04 pc 000342f4 /system/lib/libgui.so (android::BufferQueueProducer::queueBuffer(int, android::IGraphicBufferProducer::QueueBufferInput const&, android::IGraphicBufferProducer::QueueBufferOutput*)+2580)
- #00,#01,#02表示函数调用栈中栈帧的编号,编号越小的栈帧表示着当前最近调用的函数信息,所以栈帧标号#00表示的就是当前正在执行并导致程序崩溃函数的信息。
- pc后面的16进制数值表示的是当前函数正在执行的语句在共享链接库或者可执行文件中的位置
- /system/lib/libui.so表示的是当前执行指令是在哪个文件当中
- 小括号则是注明对应的是哪个函数
例如,在上面的例子中,我们就可以定位到是程序是在Fence :: waitForever(char const *)中出现了错误,但是具体在那一行呢,我们还不是特别清楚,所以就需要我们进一步地使用更加高级的工具来帮助我们解析tombstone中有关调用栈的信息。
堆叠每个通话的内容
略
处理工具
Google在NDK包中为我们提供了一系列的调试工具:
- addr2line
- objdump
- ndk-stack
在介绍上述工具的使用方法之前有必要再次介绍一下so文件的构成,虽然这部分内容属于NDK范畴。
so
文件介绍
so文件组成
完整的 .so
文件由 C/C++代码和一些 debug 信息组成,这些 debug 信息会记录 .so中
所有方法的对照表,就是方法名和其偏移地址的对应表,也叫做符号表symbolic
信息,这种.so
被称为未strip
的,通常体积会比较大。
注意:
- 符号表可以类比为 Java 代码混淆中的 mapping 文件,只有拥有这个 mapping 文件才能进行堆栈分析。
- 编译完so文件后,需要保留「机器码+debug信息的完整so文件」或者「仅含debug信息的符号表文件」
可以通过file命令查看so文件基本信息,以判断是否包含debug信息:
# 查看已被stripped的so文件
file libbreakpad-core-s.so
libbreakpad-core-s.so: *******, BuildID[sha1]=54ad86d708f4dc0926ad220b098d2a9e71da235a, stripped
# 查看未被stripped的so文件
file libbreakpad-core.so
libbreakpad-core.so: ******, BuildID[sha1]=54ad86d708f4dc0926ad220b098d2a9e71da235a, with debug_info, not stripped
so文件获取
目前 Android Studio 无论是使用 mk 或者 Cmake 编译的方式都会同时输出 strip 和未 strip 的 so:
- strip 之前的 so 路径:{project}/app/build/intermediates/merged_native_libs
- strip 之后的 so 路径:{project}/app/build/intermediates/stripped_native_libs
如下图是 Cmake 编译 so 产生的两个对应的 so:


addr2line
该工具通过输入so文件和backtrace中的地址来输出源码中的行号,支持一次性输入多个地址。
工具路径:
- Mac OS:
$NDK_ROOT/toolchains/x86-4.9/prebuilt/darwin-x86_64/bin/i686-linux-android-addr2line
最佳实践:
alias addr2line='$NDK_HOME/toolchains/x86-4.6/prebuilt/linux-x86/bin/i686-linux-android-addr2line'
注意:
- so文件需要带符号表,位于
out/target/product/cc_company/symbols/system/lib
;- 由于是逐行解析,因此想要得到完整的源码调用栈需要自行封装写个脚本工具;
用法
Usage:android-addr2line [option(s)] [addr(s)]Convert addresses into line number/file name pairs.If no addresses are specified on the command line, they will be read from stdinThe options are:@<file> Read options from <file>-a --addresses Show addresses-b --target=<bfdname> Set the binary file format-e --exe=<executable> Set the input file name (default is a.out)-i --inlines Unwind inlined functions-j --section=<name> Read section-relative offsets instead of addresses-p --pretty-print Make the output easier to read for humans-s --basenames Strip directory names-f --functions Show function names-C --demangle[=style] Demangle function names-h --help Display this information-v --version Display the program's versionandroid-addr2line: supported targets: elf32-i386 elf32-iamcu a.out-i386-linux pei-i386 elf64-x86-64 elf32-x86-64 pei-x86-64 elf64-l1om elf64-k1om elf64-little elf64-big elf32-little elf32-big plugin srec symbolsrec verilog tekhex binary ihex
Report bugs to <http://www.sourceware.org/bugzilla/>
推荐:
add2line -fCp -e /path/to/xxx.so \<addresses\>
示例
执行命令:
addr2line -f -e libui.so 00006639
输出结果:
_ZN7android5Fence11waitForeverEPKc
/home/woshijpf/newspace/android-x86/frameworks/native/libs/ui/Fence.cpp:59
ndk-stack
可将墓碑文件中的backtrace和stack完整还原成源码文件路径+代码行号的呈现方式。
工具路径:$NDK_HOME/ndk-stack
注意:
- 需要obj目录,例如
obj/local/x86/
- 通常用于本地调试阶段的问题排查,对于线上问题排查时不一定保留这些符号表文件
用法
Usage:ndk-stack -sym <path> [-dump <path>]-sym Contains full path to the root directory for symbols.-dump Contains full path to the file containing the crash dump.This is an optional parameter. If ommited, ndk-stack willread input data from stdin
- sym: 需要输入符号表文件的根目录,即obj目录
- dump:输入指定的trace文本文件路径或者若缺省则从标准输入读取
示例
原墓碑文件内容:
// tombstone_01 文件内容
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'Android-x86/android_x86/x86:5.1.1/LMY48W/woshijpf04211939:eng/test-keys'
Revision: '0'
ABI: 'x86'
pid: 2125, tid: 2125, name: androidvncserve >>> androidvncserver <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0eax 00000000 ebx b76ffff4 ecx b6a37000 edx 00000000esi 00000000 edi 00000000xcs 00000073 xds 0000007b xes 0000007b xfs 00000000 xss 0000007beip b75a4ec5 ebp bfa9bd08 esp bfa9bbf0 flags 00010246backtrace:#00 pc 0004bec5 /system/bin/androidvncserver#01 pc 0004e3e4 /system/bin/androidvncserver#02 pc 0001365a /system/lib/libc.so (__libc_init+106)#03 pc 0001060c /system/bin/androidvncserverstack:bfa9bbb0 bfa9bbc8 [stack]bfa9bbb4 b72c6fb0 /system/lib/libdvnc_flinger_sdk22.sobfa9bbb8 b72c7004 /system/lib/libdvnc_flinger_sdk22.sobfa9bbbc b72c5b26 /system/lib/libdvnc_flinger_sdk22.so (readfb_flinger+38)bfa9bbc0 b68ae080 bfa9bbc4 00000000 bfa9bbc8 00000000 bfa9bbcc 00000000 bfa9bbd0 00000000 bfa9bbd4 b76ffff4 /system/bin/androidvncserverbfa9bbd8 b76a5e20 /system/bin/androidvncserverbfa9bbdc b75ac181 /system/bin/androidvncserverbfa9bbe0 b75ac16b /system/bin/androidvncserverbfa9bbe4 b76ffff4 /system/bin/androidvncserverbfa9bbe8 bfa9bd08 [stack]bfa9bbec b75a579b /system/bin/androidvncserver#00 bfa9bbf0 00000012 bfa9bbf4 bfa9bc1c [stack]bfa9bbf8 00000000 bfa9bbfc 00000000 bfa9bc00 bfa9bc14 [stack]bfa9bc04 00000000 bfa9bc08 00000000 bfa9bc0c b7498825 /system/lib/libc.so (je_free+453)bfa9bc10 0000000e bfa9bc14 00000400 bfa9bc18 00000000 bfa9bc1c b749538a /system/lib/libc.so (je_malloc+778)bfa9bc20 0000000c bfa9bc24 00000065 bfa9bc28 00000000 bfa9bc2c b6a37000 ........ ........#01 bfa9bd10 b6bb7300 bfa9bd14 00001b58 bfa9bd18 b76aa954 /system/bin/androidvncserverbfa9bd1c 0000000b bfa9bd20 00000005 bfa9bd24 00000000 bfa9bd28 00000000 bfa9bd2c 00000005 bfa9bd30 00000006 bfa9bd34 00000005 bfa9bd38 00000000 bfa9bd3c 00000000 bfa9bd40 00000000 bfa9bd44 bfa9bd24 [stack]bfa9bd48 b754f9c8 /system/bin/linkerbfa9bd4c b7557bd8 /system/bin/linker........ ........#02 bfa9bed0 00000001 bfa9bed4 bfa9bf14 [stack]bfa9bed8 bfa9bf1c [stack]bfa9bedc 00000000 bfa9bee0 b7556fec /system/bin/linkerbfa9bee4 bfa9bf10 [stack]bfa9bee8 00000000 bfa9beec b7556fec /system/bin/linkerbfa9bef0 bfa9bf10 [stack]bfa9bef4 00000000 bfa9bef8 bfa9bf0c [stack]bfa9befc b756960d /system/bin/androidvncserver#03 bfa9bf00 bfa9bf10 [stack]bfa9bf04 00000000 bfa9bf08 b756960d /system/bin/androidvncserverbfa9bf0c b7569612 /system/bin/androidvncserverbfa9bf10 00000001 bfa9bf14 bfa9cb05 [stack]bfa9bf18 00000000 bfa9bf1c bfa9cb16 [stack]bfa9bf20 bfa9cb35 [stack]bfa9bf24 bfa9cb48 [stack]bfa9bf28 bfa9cba3 [stack]bfa9bf2c bfa9cbae [stack]bfa9bf30 bfa9cbc1 [stack]bfa9bf34 bfa9cbdc [stack]bfa9bf38 bfa9cbe7 [stack]bfa9bf3c bfa9cbfd [stack]
执行命令:
ndk-stack -sym obj/local/x86/ -dump ~/android-x86-debug-log/tombstone_01
输出结果:
********** Crash dump: **********
Build fingerprint: 'Android-x86/android_x86/x86:5.1.1/LMY48W/woshijpf04211939:eng/test-keys'
pid: 2125, tid: 2125, name: androidvncserve >>> androidvncserver <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
Stack frame #00 pc 0004bec5 /system/bin/androidvncserver: Routine update_screen_16 in /home/woshijpf/android_workspace/droidVNCserver-real/jni/vnc/updateScreen.c:68
Stack frame #01 pc 0004e3e4 /system/bin/androidvncserver: Routine main in /home/woshijpf/android_workspace/droidVNCserver-real/jni/vnc/droidvncserver.c:805
Stack frame #02 pc 0001365a /system/lib/libc.so (__libc_init+106)
Stack frame #03 pc 0001060c /system/bin/androidvncserver: Unable to locate routine information for address 1060c in module obj/local/x86//androidvncserver
Stack frame #00 pc 0007bf71 /system/lib/libc.so (nanosleep+17)
Stack frame #01 pc 00047ed6 /system/lib/libc.so (usleep+70)
Stack frame #02 pc 0004fa6b /system/bin/androidvncserver: Routine camera_io in /home/woshijpf/android_workspace/droidVNCserver-real/jni/vnc/camera_io.c:557
Stack frame #03 pc 0004af6a /system/bin/androidvncserver: Routine receive_camera in /home/woshijpf/android_workspace/droidVNCserver-real/jni/vnc/droidvncserver.c:273
Stack frame #04 pc 00022168 /system/lib/libc.so (__pthread_start(void*)+56)
Stack frame #05 pc 0001cc69 /system/lib/libc.so (__start_thread+25)
Stack frame #06 pc 000137c6 /system/lib/libc.so (__bionic_clone+70)
Stack frame #00 pc 0007cc33 /system/lib/libc.so (recvfrom+19)
Stack frame #01 pc 00050cdb /system/bin/androidvncserver: Routine handle_connections in /home/woshijpf/android_workspace/droidVNCserver-real/jni/vnc/gui.c:105
Stack frame #02 pc 00022168 /system/lib/libc.so (__pthread_start(void*)+56)
Stack frame #03 pc 0001cc69 /system/lib/libc.so (__start_thread+25)
Stack frame #04 pc 000137c6 /system/lib/libc.so (__bionic_clone+70)
objdump
使用objdump命令对目标文件(obj)或可执行文件进行反汇编,它以一种可阅读的格式让你更多的了解二进制文件可能带有的附加信息。
参考文章:objdump的使用
参考资料
- 谷歌官方教程:调试 Android 平台原生代码
- Android NDK墓碑/崩溃分析_android墓碑文件_Lixby的博客-CSDN博客
- Android的墓碑 - 掘金
- Android 平台 Native Crash 问题分析与定位
相关文章:

【NDK系列】Android tombstone文件分析
文件位置 data/tombstone/tombstone_xx.txt 获取tombstone文件命令: adb shell cp /data/tombstones ./tombstones 触发时机 NDK程序在发生崩溃时,它会在路径/data/tombstones/下产生导致程序crash的文件tombstone_xx,记录了死亡了进程的…...

CentOS7 Hive2.3.8安装
CentOS7 Hive2.3.8 安装 建议从头用我的博客,如果用外教的文件到 一、9)步骤了,就用他的弄完,数据库不一样,在9步骤前还能继续看我的 一、 安装MySQL 0.0)查询mariadb,有就去0.1),没有就不管…...
代码随想录算法训练营第四十四天 完全背包 、零钱兑换 II 、组合总和 Ⅳ
代码随想录算法训练营第四十四天 | 完全背包 、零钱兑换 II 、组合总和 Ⅳ 完全背包 题目链接:题目页面 (kamacoder.com) 解释一、01背包 一维 :为什么要倒序遍历背包? 首先要明白二维数组的递推过程,然后才能看懂二维变一维的…...

【经验】vscode 鼠标拖曳不能选中整行文字,只能选中纵向矩形范围
1、问题描述 不知道昨天操作vscode设置界面时,误选择了啥,导致鼠标拖曳不能选中整行文字,只能选中纵向矩形范围,现象如下: 2、解决方法 1)打开设置界面 点击左下角按键,选择“设置” 2&…...

Redis--事务机制的详解及应用
Redis事务的概念: Redis事务就是将一系列命令包装成一个队列,在执行时候按照添加的顺序依次执行,中间不会被打断或者干扰,在执行事务中,其他客户端提交的命令不可以插入到执行事务的队列中,简单来说Redis事…...

路由器端口映射如何配置?
在网络通信中,路由器是一个重要的设备,它负责将数据包从一个网络传输到另一个网络。路由器的端口映射配置是一种重要的设置,可以使外部网络中的计算机通过访问路由器上的特定端口与内部网络中的计算机进行通信。本文将介绍什么是路由器端口映…...

力扣34. 在排序数组中查找元素的第一个和最后一个位置(二分查找)
Problem: 34. 在排序数组中查找元素的第一个和最后一个位置 文章目录 题目描述思路复杂度Code 题目描述 思路 Problem: 二分查找常用解题模板(带一道leetcode题目) 直接套用上述中的寻找左、右边界的二分查找模板即可 复杂度 时间复杂度: O ( l o g n )…...

【每日一题】3.2 求逆序对
题目描述 给定一个长度为 n的整数数列,请你计算数列中的逆序对的数量。 逆序对的定义如下:对于数列的第 i个和第 j个元素,如果满足 i<j 且 a[i]>a[j],则其为一个逆序对;否则不是。 输入格式 第一行包含整数 n…...
NTP时间源服务器(NTP网络时钟)助力智慧医院数字化
NTP时间源服务器(NTP网络时钟)助力智慧医院数字化 NTP时间源服务器(NTP网络时钟)助力智慧医院数字化 目前计算机网络中各主机和服务器等网络设备的时间基本处于无序的状态。 随着计算机网络应用的不断涌现,计算机的时…...

Benchmark学习笔记
小记一篇Benchmark的学习笔记 1.什么是benchmark 在维基百科中,是这样子讲的 “As computer architecture advanced, it became more difficult to compare the performance of various computer systems simply by looking at their specifications.Therefore, te…...

Linux中的动静态库
目录 一、静态库 (1)静态库的优缺点: (2)Linux下静态库的创建和执行 1.直接编译编辑 2.指定路径和库名 3.用LIBRARY_PATH环境变量来配置路径 二、动态库 (1)动态库的优缺点 ÿ…...

C/C++基础语法
C/C基础语法 文章目录 C/C基础语法头文件经典问题链表链表基础操作 秒数转换闰年斐波那契数列打印n阶菱形曼哈顿距离菱形图案的定义大数计算 输入输出格式化输入输出getline()函数解决cin只读入一个单词的问题fgets读入整行输出字符数组(两种方式puts和printf&#…...

Home Assistant:基于Python的智能家居开源系统详解
Home Assistant:基于Python的智能家居开源系统详解 在数字化和智能化的时代,智能家居系统成为了现代家庭的新宠。它们能够让我们更加方便地控制家中的各种设备,实现自动化和个性化的居住体验。其中,Home Assistant作为一款基于Pyt…...
使用vscode进行简单的多文件编译
安装好必要的插件后(如C/C,code runner等)默认生成task.json即可进行单文件运行 涉及到多文件情况可以修改task.json如下: {"version": "2.0.0","tasks": [{"type": "cppbuild&quo…...

Python实现PPT演示文稿中视频的添加、替换及提取
无论是在教室、会议室还是虚拟会议中,PowerPoint 演示文稿都已成为一种无处不在的工具,用于提供具有影响力的可视化内容。PowerPoint 提供了一系列增强演示的功能,在其中加入视频的功能可以大大提升整体体验。视频可以传达复杂的概念、演示产…...

Mysql学习之MVCC解决读写问题
多版本并发控制 什么是MVCC MVCC (Multiversion Concurrency Control)多版本并发控制。顾名思义,MVCC是通过数据行的多个版本管理来实现数据库的并发控制。这项技术使得在InnoDB的事务隔离级别下执行一致性读操作有了保证。换言之࿰…...
Linux下如何生成coredump文件
引言 在linux下执行程序,当出现coredump时,却发现没有生成core文件,或者生成了core文件却不知道在哪里,下面就讲述如何产出core文件,以及指定core文件的产出格式与路径。 打开core文件的大小限制 ulimit -c unlimit…...

eltable 合计行添加tooltip
eltable 合计行添加tooltip 问题描述: eltable 合计行单元格内容过长会换行,需求要求合计行数据超长显示 … ,鼠标 hover 时显示提示信息。 解决方案:eltable合计行没有对外的修改接口,想法是 自己实现一个tooltip&a…...
Secure Boot(安全启动)
Secure Boot(安全启动)的原理基于链式验证,这是一种确保计算机在启动过程中只加载和执行经过认证的软件的机制。这个过程涉及到硬件、固件和操作系统的多个层面。以下是Secure Boot的基本原理: 密钥和证书:Secure Boot…...
大厂面试经验:如何对加密后的数据进行模糊查询操作
加密后的数据对模糊查询不是很友好,本篇就针对加密数据模糊查询这个问题来展开讲一讲实现的思路。 为了数据安全我们在开发过程中经常会对重要的数据进行加密存储,常见的有:密码、手机号、电话号码、详细地址、银行卡号、信用卡验证码等信息…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

密码学基础——SM4算法
博客主页:christine-rr-CSDN博客 专栏主页:密码学 📌 【今日更新】📌 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 编辑…...
python打卡第47天
昨天代码中注意力热图的部分顺移至今天 知识点回顾: 热力图 作业:对比不同卷积层热图可视化的结果 def visualize_attention_map(model, test_loader, device, class_names, num_samples3):"""可视化模型的注意力热力图,展示模…...
用鸿蒙HarmonyOS5实现国际象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的国际象棋小游戏的完整实现代码,使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├── …...

OPENCV图形计算面积、弧长API讲解(1)
一.OPENCV图形面积、弧长计算的API介绍 之前我们已经把图形轮廓的检测、画框等功能讲解了一遍。那今天我们主要结合轮廓检测的API去计算图形的面积,这些面积可以是矩形、圆形等等。图形面积计算和弧长计算常用于车辆识别、桥梁识别等重要功能,常用的API…...

C# WPF 左右布局实现学习笔记(1)
开发流程视频: https://www.youtube.com/watch?vCkHyDYeImjY&ab_channelC%23DesignPro Git源码: GitHub - CSharpDesignPro/Page-Navigation-using-MVVM: WPF - Page Navigation using MVVM 1. 新建工程 新建WPF应用(.NET Framework) 2.…...