高效内存管理与调试技巧:深入解析 AddressSanitizer
在现代 C++开发中,内存管理是一个至关重要但也容易出错的领域。即使使用了智能指针和其他高效工具,复杂的项目仍可能出现内存泄漏、非法访问等问题。为了解决这些问题,Google 开发了一个强大的工具——AddressSanitizer (ASan)。本文将详细介绍如何使用 ASan 高效调试内存问题,以及一些常见的最佳实践。
2. 什么是 AddressSanitizer?
AddressSanitizer 是一种快速内存错误检测工具,可以捕捉以下几类内存问题:
-
越界访问(Out-of-Bounds Access): 访问数组或容器之外的内存。例如:
#include <iostream>int main() {int arr[5] = {0};arr[5] = 10; // 越界访问return 0; }
-
堆使用后释放(Use-After-Free): 访问已经被释放的堆内存。例如:
#include <iostream>int main() {int* ptr = new int(10);delete ptr;*ptr = 20; // 使用已释放的内存return 0; }
-
堆内存泄漏(Memory Leaks): 未正确释放的堆内存。例如:
#include <iostream>int main() {int* ptr = new int[10];// 未释放分配的内存return 0; }
-
栈缓冲区溢出(Stack Buffer Overflow): 非法访问栈上的内存。例如:
#include <iostream>void recursive() {int arr[1000];recursive(); // 导致栈溢出 }int main() {recursive();return 0; }
-
全局缓冲区越界(Global Buffer Overflow): 访问全局变量分配的内存之外的区域。例如:
#include <iostream>char global_arr[10];int main() {global_arr[10] = 'A'; // 越界访问全局缓冲区return 0; }
-
返回后使用(Use-After-Return): 访问已退出函数的栈变量。
#include <iostream>int* dangling_pointer() {int local_var = 42;return &local_var; // 返回局部变量的地址 }int main() {int* ptr = dangling_pointer();std::cout << *ptr << std::endl; // 使用悬空指针return 0; }
-
作用域外使用(Use-After-Scope): 访问已超出作用域的变量。
#include <iostream> #include <string>int main() {std::string* ptr;{std::string local_str = "hello";ptr = &local_str;} // local_str超出作用域std::cout << *ptr << std::endl; // 使用无效指针return 0; }
-
初始化顺序错误(Initialization Order Bugs): 在全局变量的构造函数中访问未初始化的变量。
#include <iostream>struct A {A() { std::cout << b << std::endl; } // 访问未初始化的bstatic int b; };int A::b = 42;int main() {A a;return 0; }
2. 如何开启
编译器 flag
新近的编译机基本都支持 asan,下面是如何开启
- 在 GCC 或 Clang 中,启用 ASan 只需简单的编译选项:
-fsanitize=address
CMake 设置
在使用 CMake 的项目中,可以通过以下配置启用 ASan:
-
全局设置
add_compile_options(-fsanitize=address) add_link_options(-fsanitize=address)
-
也可以为单独的 target 设置
target_compile_options(target -fsanitize=address) target_link_options(target -fsanitize=address)
5. AddressSanitizer 的错误报告
1. 错误输出
运行上述的越界访问的样例,程序会产生错误输出,内容如下
=================================================================
==58410==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x78be1a309034 at pc 0x599c6544a334 bp 0x7fffd3283890 sp 0x7fffd3283880
WRITE of size 4 at 0x78be1a309034 thread T0#0 0x599c6544a333 in main /home/aronic/playground/CSDNBlogSampleCode/address-sanitizer/out-of-bound.cpp:4#1 0x78be1c42a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58#2 0x78be1c42a28a in __libc_start_main_impl ../csu/libc-start.c:360#3 0x599c6544a124 in _start (/home/aronic/playground/CSDNBlogSampleCode/build/out-of-bound+0x1124) (BuildId: 81ed0f02ffd8359b35cb7455896699d9e2b084bc)Address 0x78be1a309034 is located in stack of thread T0 at offset 52 in frame#0 0x599c6544a1f8 in main /home/aronic/playground/CSDNBlogSampleCode/address-sanitizer/out-of-bound.cpp:2This frame has 1 object(s):[32, 52) 'arr' (line 3) <== Memory access at offset 52 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/aronic/playground/CSDNBlogSampleCode/address-sanitizer/out-of-bound.cpp:4 in main
Shadow bytes around the buggy address:0x78be1a308d80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x78be1a308e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x78be1a308e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x78be1a308f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x78be1a308f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x78be1a309000: f1 f1 f1 f1 00 00[04]f3 f3 f3 f3 f3 00 00 00 000x78be1a309080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x78be1a309100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x78be1a309180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x78be1a309200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x78be1a309280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):Addressable: 00Partially addressable: 01 02 03 04 05 06 07Heap left redzone: faFreed heap region: fdStack left redzone: f1Stack mid redzone: f2Stack right redzone: f3Stack after return: f5Stack use after scope: f8Global redzone: f9Global init order: f6Poisoned by user: f7Container overflow: fcArray cookie: acIntra object redzone: bbASan internal: feLeft alloca redzone: caRight alloca redzone: cb
==58410==ABORTING
这个 ASan 输出详细地报告了程序中发生的**栈缓冲区溢出(stack-buffer-overflow)**错误,以下是解读每个关键部分的详细说明:
2. 错误概要
==58410==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x78be1a309034 at pc 0x599c6544a334 bp 0x7fffd3283890 sp 0x7fffd3283880
WRITE of size 4 at 0x78be1a309034 thread T0
- 错误类型:
stack-buffer-overflow
表示在栈上的数组发生了越界访问。 - 地址:
0x78be1a309034
是出错的内存地址。 - 线程:
T0
表示发生错误的线程是主线程。 - 操作类型:
WRITE of size 4
,表明代码试图向越界地址写入 4 个字节的数据(可能是一个int
类型)。
3. 错误发生的代码位置
#0 0x599c6544a333 in main /home/aronic/playground/CSDNBlogSampleCode/address-sanitizer/out-of-bound.cpp:4
- 错误发生在文件
/home/aronic/playground/CSDNBlogSampleCode/address-sanitizer/out-of-bound.cpp
的第 4 行代码中。 - 堆栈追踪(stack trace)显示了函数调用链中错误的位置:这里是
main
函数。
4. 详细地址信息
Address 0x78be1a309034 is located in stack of thread T0 at offset 52 in frame#0 0x599c6544a1f8 in main /home/aronic/playground/CSDNBlogSampleCode/address-sanitizer/out-of-bound.cpp:2
- 地址:出错地址
0x78be1a309034
位于栈帧中,从栈帧的起始偏移量52
开始。 - 函数:
main
是栈帧所属的函数。
5. 变量信息
This frame has 1 object(s):[32, 52) 'arr' (line 3) <== Memory access at offset 52 overflows this variable
- 变量:
arr
是一个栈上分配的数组,位于[32, 52)
的地址范围。 - 问题:
arr
的有效范围是[32, 52)
,但访问发生在52
偏移处,超出了变量的边界。
6. 提示信息
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork(longjmp and C++ exceptions *are* supported)
- 提示一些边界情况(如
swapcontext
或vfork
)可能导致误报,但这里明显是栈溢出。
7. 总结
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/aronic/playground/CSDNBlogSampleCode/address-sanitizer/out-of-bound.cpp:4 in main
- 问题类型:
stack-buffer-overflow
- 错误位置:
out-of-bound.cpp
的第 4 行。
8. Shadow Memory 显示
Shadow bytes around the buggy address:=>0x78be1a309000: f1 f1 f1 f1 00 00[04]f3 ...
f1
:表示栈的左红区(Stack Left Redzone),即栈变量边界的保护区域。f3
:表示栈的右红区(Stack Right Redzone),越过这个区域会触发越界错误。[04]
:出错访问位置。
6. 如何配置 AddressSanitizer
ASan 提供了多种环境变量和运行时选项,以便更好地适应实际需求。以下是常见的配置选项:
6.1 环境变量
- ASAN_OPTIONS
通过设置ASAN_OPTIONS
,可以自定义 ASan 的行为。以下是一些常用参数及其用途:
detect_leaks=1
:启用内存泄漏检测(默认开启)。halt_on_error=1
:在检测到内存错误时立即停止程序运行。verbosity=1
:增加日志的详细程度,便于调试。log_to_syslog=1
:将错误日志写入系统日志,而非标准输出。allocator_may_return_null=1
:当内存分配失败时返回NULL
而非终止程序。malloc_context_size=10
:设置堆栈跟踪的深度,默认值为 10。strict_string_checks=1
:启用更严格的字符串操作检查。
这些参数可以灵活调整,以适应不同的调试需求。
示例:
export ASAN_OPTIONS=detect_leaks=1:halt_on_error=1
detect_leaks=1
启用内存泄漏检测(默认开启)。halt_on_error=1
检测到错误时立即停止程序。
- LSAN_OPTIONS
如果要单独控制内存泄漏检测,可设置LSAN_OPTIONS
。
示例:
export LSAN_OPTIONS=suppressions=leak_ignore.txt
6.2 报告压缩
为减少报告的冗长,可以启用报告压缩:
export ASAN_OPTIONS=log_to_syslog=1:verbosity=1
6.3 抑制特定错误
如果某些错误可以忽略,可以通过抑制文件指定。
示例抑制文件 suppressions.txt
:
leak:example_function
heap-buffer-overflow:another_function
运行时使用:
export ASAN_OPTIONS=suppressions=suppressions.txt
9. 内部原理
AddressSanitizer 的工作原理核心在于影子内存(Shadow Memory)和红黑树(Red-Black Tree)的使用,这些技术帮助高效检测内存问题。
-
影子内存(Shadow Memory)
- 影子内存是程序实际内存的紧凑映射,每个影子字节表示实际内存中的 8 字节状态。
- 地址映射公式:
其中ShadowAddr = (MemAddr >> 3) + Offset
Offset
是一个固定值,确保影子内存区域与实际内存隔离。 - 影子字节的值用于标记实际内存是否可访问。例如:
0
: 完全可访问。- 非零值:部分或完全不可访问。
-
插桩代码检测
- 编译器在编译时插入检查代码,每次内存分配、释放或访问都会检查影子内存。
- 如果检测到非法访问(如越界、使用已释放内存),ASan 会生成详细的错误报告。
-
红黑树存储元信息
- ASan 使用红黑树记录分配的内存块信息,包括大小和位置。
- 访问内存时,通过红黑树快速验证操作是否合法。
这种结合影子内存映射和红黑树的机制,使得 ASan 在运行时能快速、准确地捕捉内存问题,性能开销显著低于传统工具如 Valgrind,同时提供详细的上下文信息,方便开发者定位和修复问题。
8. AddressSanitizer 的最佳实践
-
开发早期启用 ASan
在开发初期就启用 ASan,可以及时发现潜在问题,避免问题堆积。这是因为早期发现问题不仅可以减少后期修复的复杂度,还能显著降低技术债务的累积。此外,ASan 的错误报告详细而直观,便于快速定位和解决问题。 -
结合其他工具使用
将 ASan 与静态分析工具(如 Clang-Tidy)结合,全面提升代码质量。 -
定期运行回归测试
在 CI/CD 管道中集成 ASan,确保代码改动不会引入新的内存问题。 -
注意性能开销
ASan 可能导致运行速度降低,建议仅在调试环境中启用。
9. 总结
AddressSanitizer 是一个高效的内存问题检测工具,特别适合现代 C++开发中的调试需求。它通过影子内存(Shadow Memory)和红黑树记录分配信息,快速检测和报告内存错误。ASan 的高效机制能显著提升代码的健壮性和性能,是开发复杂内存操作项目的重要工具。
相关文章:
高效内存管理与调试技巧:深入解析 AddressSanitizer
在现代 C开发中,内存管理是一个至关重要但也容易出错的领域。即使使用了智能指针和其他高效工具,复杂的项目仍可能出现内存泄漏、非法访问等问题。为了解决这些问题,Google 开发了一个强大的工具——AddressSanitizer (ASan)。本文将详细介绍…...
力扣第137题:只出现一次的数字 II C语言解法
力扣第137题:只出现一次的数字 II C语言解法 题目描述 给定一个整数数组 nums,其中每个元素出现三次,除了一个元素出现一次。找出那个只出现一次的元素。 说明: 你的算法应该具有线性时间复杂度。你不可以使用额外的空间&…...
【Qt】控件概述和QWidget核心属性1(enabled、geometry、windowTitle、windowIcon、QRC机制)
一、控件概念 界面上各种元素、各种部分的统称(如按钮、输入框、下拉框、单选复选框...) Qt作为GUI开发框架,内置了各种的常用控件,并支持自定义控件。 二、控件体系发展 1.没有完全的控件,需要使用绘图API手动绘制…...
25年1月更新。Windows 上搭建 Python 开发环境:PyCharm 安装全攻略(文中有安装包不用官网下载)
python环境没有安装的可以点击这里先安装好python环境,python环境安装教程 安装 PyCharm IDE 获取 PyCharm PyCharm 提供两种主要版本——社区版(免费)和专业版(付费)。对于初学者和个人开发者而言,社区…...
软件工程大复习之(四)——面向对象与UML
4.1 面向对象概述 面向对象(OO)是一种编程范式,它将数据和处理数据的方法封装在对象中。面向对象的主要概念包括: 对象:实例化的数据和方法的集合。类:对象的蓝图或模板。封装:隐藏对象的内部…...
前端基础函数算法整理应用(sort+reduce+date+双重for循环)
文章目录 基础函数算法reduce 函数算法sort 函数算法时间排序1. 对日期字符串数组进行排序2. 对包含日期对象的数组进行排序3. 对包含时间戳的数组进行排序4. 对包含日期时间信息的对象数组进行排序 基础函数算法 一、排序算法 冒泡排序(Bubble Sort) …...
web系统漏洞攻击靶场
摘 要 互联网极速发展的同时,也会带来一些安全性的风险,一些不为人知的安全问题也逐渐暴露出来。近年来,媒体不断披露了许多网络安全事故,许多网络应用程序被黑客攻击,导致内部数据外泄,人们开始认识到网络…...
苍穹外卖-day07(Spring Cache 购物车业务逻辑)
内容 缓存菜品缓存套餐添加购物车查看购物车清空购物车 功能实现:缓存商品、购物车 效果图: 1. 缓存菜品 1.1 问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增…...
win10 VS2019上libtorch库配置过程
win10 VS2019上libtorch库配置过程 0 引言1 获取libtorch2 在VS上配置使用libtorch库3 结语 0 引言 💻💻AI一下💻💻 libtorch库是一个用于深度学习的C库,是PyTorch的官方C前端。它提供了用于构建和训练深度学习模…...
git 常用命令和本地合并解决冲突
目录 一、常用命令 二、本地可视化合并分支解决冲突 一、常用命令 最近,使用mac电脑,无法直接使用小乌龟进行可视化操作,现在记录一些常用命令。 拉取: git clone <git url> 仅拉起某个单独分支: git clo…...
Elasticsearch 创建索引 Mapping映射属性 索引库操作 增删改查
Mapping Type映射属性 mapping是对索引库中文档的约束,有以下类型。 text:用于分析和全文搜索,通常适用于长文本字段。keyword:用于精确匹配,不会进行分析,适用于标签、ID 等精确匹配场景。integer、long…...
Objective-C语言的数据结构
Objective-C语言中的数据结构 Objective-C是一种面向对象的编程语言,其在苹果公司的软件开发中得到了广泛应用。它主要用于开发macOS和iOS应用程序。虽然Objective-C有许多丰富的特性,但在程序设计中,数据结构仍然是构建任何应用程序的基础。…...
智能水文:ChatGPT等大语言模型如何提升水资源分析和模型优化的效率
大语言模型与水文水资源领域的融合具有多种具体应用,以下是一些主要的应用实例: 1、时间序列水文数据自动化处理及机器学习模型: ●自动分析流量或降雨量的异常值 ●参数估计,例如PIII型曲线的参数 ●自动分析降雨频率及重现期 ●…...
ETL的工作原理
ETL的工作原理 什么是ETL_云计算主题库-阿里云 ETL的工作原理可以分为三个主要的步骤:Extract(提取)、Transform(转换)、Load(加载)。 工作步骤 描述 Extract (提取)…...
黑马头条平台管理实战
黑马头条 08平台管理 1.开始准备和开发思路1.1.开发网关1.2编写admin-gateway 代码 2.开发登录微服务2.1编写登录微服务 3.频道管理4.敏感词管理5.用户认证审核6.自媒体文章人工审核99. 最后开发中碰到的问题汇总1.关于nacos 配置 问题2.在开发频道管理新增频道后端无法接收到前…...
电池管理系统(BMS)架构详细解析:原理与器件选型指南
BMS(电池管理系统)架构详细讲解 从你提供的BMS(Battery Management System)架构图来看,主要涉及到电池监控模块、通信模块、功率控制模块等部分。下面我将详细讲解该架构的各个功能模块及其工作原理。 1. 电池管理核…...
SpringBoot环境和Maven配置
SpringBoot环境和Maven配置 1. 环境准备2. Maven2.1 什么是Maven2.2 为什么要学 Maven2.3 创建一个 Maven项目2.4 Maven核心功能2.4.1 项目构建2.4.2 依赖管理2.4.3 Maven Help插件 2.5 Maven 仓库2.5.1本地仓库2.5.2 中央仓库2.5.3 私有服务器, 也称为私服 2.6 Maven设置国内源…...
lambda用法及其原理
目录 lambda形式lambda用法1.sort降序2.swap3.捕捉列表 习题解题 lambda形式 [capture-list](parameters)->return type{function boby}[capture-list]:[捕捉列表]用于捕捉函数外的参数,可以为空,但不能省略;(parameters) &am…...
Postgresql源码(139)vim直接修改postgresql表文件的简单实例
1 前言 PG可以用pageinspect方便的读取查看表文件。本篇介绍一种用vim查看、编辑的方法,案例比较简单,主要分享原理。 修改表文件和controlfile是非常危险的行为,请不要在生产尝试。 2 用例 简化问题,用简单编码的数据类型。 d…...
Lianwei 安全周报|2025.1.2
以下是本周「Lianwei周报」,我们总结推荐了本周的政策/标准/指南最新动态、热点资讯和安全事件,保证大家不错过本周的每一个重点! 政策/标准/指南最新动态 01 国家数据局等五部门印发《关于促进企业数据资源开发利用的意见》 为充分释放企业…...
Vue3-跨层组件通信Provide/Inject机制详解
Vue 3 中的 Provide 和 Inject 机制是专为跨层级传递数据而设计的,适用于祖先组件和后代组件之间的通信。与props 和 emits 不同,Provide/Inject 可以跨越多个层级进行数据传递,而不需要逐层传递。 1. Provide provide 是一个在祖先组件中提…...
springcloud 介绍
Spring Cloud是一个基于Spring Boot的微服务架构解决方案集合,它提供了一套完整的工具集,用于快速构建分布式系统。在Spring Cloud的架构中,服务被拆分为一系列小型、自治的微服务,每个服务运行在其独立的进程中,并通过…...
css预处理器sass
在前端开发的世界中,CSS 是构建网页样式的基础。然而,随着项目规模的增大,纯 CSS 的编写和维护往往会变得复杂而繁琐。为了解决这些痛点,Sass(Syntactically Awesome Style Sheets)应运而生。Sass 是一种 C…...
匠人天工Ai浮雕网站创新发布了ZBrush插件,提效500%,为AI+数字雕刻行业带来新的活力
2025年1月6日,杭州——杭州仓颉造梦数字科技公司旗下产品匠人天工近日宣布推出一款创新的ZBrush插件,旨在为AI数字雕刻行业带来前所未有的效率提升。该插件通过一系列智能化功能,大幅简化了数字雕刻的建模流程,使建模效率提高了50…...
解决 Pangolin 版本不兼容导致的编译错误
在使用 Pangolin 库时,有时候会遇到由于版本不兼容而导致的编译错误。本文将通过一个具体的错误案例,展示如何识别和解决这种问题。 问题描述 在编译时,遇到如下编译错误: /usr/local/include/pangolin/gl/glsl.hpp: In member…...
day01_ Java概述丶开发环境的搭建丶常用DOS命令
编程常识 什么是编程? 所谓编程,就是人们可以使用编程语言对计算机下达命令,让计算机完成人们需要的功能。 编程语言的发展历程 第一代:机器语言 ,机器语言由数字组成所有指令。计算器解析运行速度,最快…...
进程间通信——网络通信——UDP
进程间通信(分类):网络通信、无名管道、有名管道、信号、消息队列、共享内存、信号量集 OSI七层模型:(理论模型) 应用层 : 要传输的数据信息,如文件传输,电子邮件等 表示层 : 数…...
(六)vForm 动态表单(数据量大,下拉选卡顿问题)
系列文章目录 (一)vForm 动态表单设计器之使用 (二)vForm 动态表单设计器之下拉、选择 (三)vForm 动态表单解决下拉框无数据显示id问题 (四)vForm 动态表单自定义组件、属性 (五)vForm 动态表单文件上传、下载 文章目录 目录 前言 一、组件改造 1.添加分页所需参…...
asp.net core mvc的 ViewBag , ViewData , Module ,TempData
在 ASP.NET MVC 和 ASP.NET Core MVC 中,ViewBag 和 ViewData 是两种用于将数据从控制器传递到视图(View)的常用方法。它们都允许控制器将动态数据传递给视图,但它们的实现方式有所不同。关于 Module,它通常指的是某种…...
C#语言的软件开发工具
C#语言的软件开发工具 C#语言作为一种现代化的编程语言,凭借其强大的功能和丰富的生态系统,在软件开发领域得到了广泛的应用。随着C#语言的发展,越来越多的开发工具应运而生。本文将详细介绍C#语言常用的开发工具,包括集成开发环…...
iOS - AutoreleasePool
1. 基本数据结构 // AutoreleasePool 的基本结构 struct AutoreleasePoolPage {static pthread_key_t const key AUTORELEASE_POOL_KEY;magic_t const magic;id *next; // 指向下一个可存放对象的地址pthread_t const thread; // 所属线程AutoreleasePoolPage …...
数据仓库建设方案和经验总结
在做数据集成的过程中,往往第二步的需求就是建设数仓由于数据分散在不同的存储环境或数据库中,对于新业务需求的开发需要人工先从不同的数据库中同步、集中、合并等处理,造成资源和人力的浪费。同时,目前的系统架构,无…...
该单据从未生成交易分录
经常听到采购说,采购匹配明细表中没有xx料号的记录,没有xx供应商的记录。它们用这个报表来与供应商对账的。每每以此为借口拖延着货款不付。没有记录出来,原因各种。之前没有记录下来,想不起来。今天重新分析发现其中一个原因&…...
Flink DataSet API
文章目录 DataSet SourcesDataSet TransformationDataSet Sink序列化器样例一:读 csv 文件生成 csv 文件样例二:读 starrocks 写 starrocks样例三:DataSet、Table Sql 处理后写入 StarRocksDataSet<Row> 遍历遇到的坑 分类:…...
Bash Shell的操作环境
目录 1、路径与指令搜寻顺序 2、bash的进站(开机)与欢迎信息:/etc/issue,/etc/motd (1)/etc/issue (2)/etc/motd 3、bash的环境配置文件 (1)login与non-…...
web自动化测试环境搭建(python环境下selenium)
环境搭建步骤 安装selenium pip install selenium 安装浏览器 安装浏览器驱动 谷歌浏览器:chromdriver.exe ie浏览器:ieserverdriver.exe FireFox浏览器:geckodriver.exe 特别注意⚠️:下载驱动版本必须与浏览器版本一致 下载地址 淘宝镜像࿱…...
解决cursor AI编辑器控制台console中文乱码
chcp 查看当前控制台编码 936 : gbk编码 控制台输入:chcp 65001 设置为utf8...
fail api scope is not declared in the privacy agreement微信小程序uniapp 解决录音无法播放、授权
已解决 fail api scope is not declared in the privacy agreement微信小程序uniapp 解决录音无法播放、授权 没有声明内容协议导致的 微信公众平台:https://mp.weixin.qq.com/【1.左下角的-移动过去后会出现 “帐号设置”】 【2.基本设置->服务内容声明->修…...
ArkTs 状态管理装饰器
在构建页面多为静态界面,如果希望构建一个动态的,有交互的界面,就需要引入‘状态’的概念。 一.基本概念 1.状态变量:被状态装饰器装饰的变量,状态变量值的改变或引起UI的渲染更新 2.常规变量:没有被状态…...
Linux CentOS 7系统如何修改panel 重新打开最小化的界面/软件/程序
CentOS 7系统下,部分用户可能一开始打开界面没有类似Windows的下方菜单栏,只有一个浮动的panel。一旦打开软件,然后点击最小化后,找不到重新打开的方法。 右键panel,点击Add New Items… 选择以下三个基本就可以了&am…...
猫的眼睛有几种颜色?
在猫咪神秘而迷人的世界里,它们的眼睛犹如璀璨星辰,闪烁着各异的光芒,颜色丰富多样,令人着迷。 猫眼睛的颜色,粗略一数,常见的便有黄色、蓝色、绿色、棕色,还有那神秘的异瞳。这些色彩并非无端生…...
200道Java面试题(2025)
Java 基础 1. JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,Java 开发工具包,提供了 Java 的开发环境和运行环境。 JRE:Java Runtime Environment 的简称,Java 运行环境,为 Java …...
ros2笔记-2.5.3 多线程与回调函数
本节体验下多线程。 python示例 在src/demo_python_pkg/demo_python_pkg/下新建文件,learn_thread.py import threading import requestsclass Download:def download(self,url,callback):print(f线程:{threading.get_ident()} 开始下载:{…...
openwrt nginx UCI配置过程
openwrt 中nginx有2种配置方法,uci nginx uci /etc/config/nginx 如下: option uci_enable true‘ 如果是true就是使用UCI配置,如果 是false,就要使用/etc/nginx/nginx.conf,一般不要修改。 如果用UCI,其…...
【数据结构】双向循环链表的使用
双向循环链表的使用 1.双向循环链表节点设计2.初始化双向循环链表-->定义结构体变量 创建头节点(1)示例代码:(2)图示 3.双向循环链表节点头插(1)示例代码:(2ÿ…...
《Python游戏编程入门》注-第9章8
2 游戏信息的显示 在游戏窗口的上部会显示游戏分数、游戏关卡、剩余砖块数以及剩余小球数等信息,如图12所示。 图12 游戏信息显示 使用如图13所示的代码实现以上功能。 图13 显示游戏信息的代码 其中,print_text()函数MyLibrary....
起重机检测数据集VOC+YOLO格式2316张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2316 标注数量(xml文件个数):2316 标注数量(txt文件个数):2316 …...
20250106面试
rabbitmq如何保证消息不丢失 my: 持久化,包括消息持久化和队列持久化,重启不丢失。持久化到磁盘中的。 消息确认 死信队列:消费失败(业务异常/未确认,重试后,会放死信队列)&…...
【大数据】(选修)实验4 安装熟悉HBase数据库并实践
实验4 安装熟悉HBase数据库并实践 1、实验目的 (1)理解HBase在Hadoop体系结构中的角色; (2)熟练使用HBase操作常用的Shell命令; (3)熟悉HBase操作常用的Java API。 2、实验平台 操作系统:Linux Hadoop版本:2.6.0或以上版本 HBase版本:1.1.2或以上版本 JDK版…...
使用Python类库pandas操作Excel表格
Date: 2025.01.02 20:33:30 author: lijianzhan 简述:pandas 是处理 Excel 文件的强大工具,它提供了简单易用的接口来读取、操作和写入 Excel 数据。以下是使用 pandas 处理 Excel 文件的详细指南,包括常见操作和示例代码。 安装依赖,pandas …...