当前位置: 首页 > news >正文

linux ptrace 图文详解(八) gdb跟踪被调试程序的子线程、子进程

目录

一、gdb跟踪被调试程序的fork、pthread_create操作

二、实现原理

三、代码实现

四、总结


(代码:linux 6.3.1,架构:arm64)

One look is worth a thousand words.  —— Tess Flanders

相关链接:

linux ptrace 图文详解(一)基础介绍

linux ptrace 图文详解(二) PTRACE_TRACEME 跟踪程序

linux ptrace 图文详解(三) PTRACE_ATTACH 跟踪程序

linux ptrace 图文详解(四) gdb设置软断点

linux ptrace 图文详解(五) gdb设置硬断点、观察点

linux ptrace 图文详解(六) gdb单步调试

linux ptrace 图文详解(七) gdb、strace跟踪系统调用

在开始之前,我们先思考几个问题:

1)gdb调试一个程序,该程序所创建的子进程、子线程,是否同样会被gdb跟踪?

2)若gdb可以跟踪被调试程序的子进程、子线程,这是如何实现的?gdb如何获取到子进程、子线程的信息?

3)gdb一定要跟踪被调试程序的子线程、子进程么?

一、gdb跟踪被调试程序的fork、pthread_create操作

        GDB 从 版本 7.0 开始支持用户显式控制是否监控被调试程序创建的子进程和子线程。以下是一些gdb控制调试子进程、子线程的一些常见指令:

        1)gdb控制子进程调试

                set follow-fork-mode <mode>

                mode选项:

                - parent(默认):仅调试父进程,子进程继续运行不受监控

                - child:切换到调试子进程,父进程继续运行

                set detach-on-fork <on/off>

                - on:分离非调试的进程(若选择跟踪子进程时,父进程会被分离)

                - off:同时调试父子进程(需配合inferior命令切换)

        2)gdb控制子线程调试

                set scheduler-locking <mode>

                mode选项:

                - off(默认):所有线程自由运行;

                - on:仅当前调试的线程运行,其他线程暂停;

                - setp:单步执行时仅当前线程运行(避免其他线程干扰);

        使用示例:

# 启动gdb设置调试模式
gdb ./test
(gdb) set follow-fork-mode child  # 跟踪子进程
(gdb) set detach-on-fork off      # 不分离父进程
(gdb) break child_function        # 在子进程函数设断点
(gdb) run# 切换进程
(gdb) info inferiorsNum  Description       Executable1    process 1234      ./test (父进程)2    process 1235      ./test (子进程)
(gdb) inferior 2  # 切换到子进程

二、实现原理

gdb跟踪被调试程序创建的子进程/子线程的原理如下:

        1)被调试程序(父进程)调用fork、pthread_create后,陷入内核的系统调用都是kernel_clone;

        2)为 子进程/子线程 创建对应的task_struct对象,并且dup相应的内核对象;

        3)子进程/子线程 的task_struct对象,继承父进程的ptrace字段(该字段的用途:控制当前进程的哪些行为需要被gdb接管,该字段通常是由gdb通过ptrace进行设置的);

        4)父进程 给 子进程/子线程 的task对象添加一个SIGSTOP信号,目的是让子进程/子线程被调度运行时将自己挂起;

        5)父进程通过wake_up_new_task 将 子进程/子线程 添加到就绪队列等待被调度运行;

        6)子进程/子线程被调度运行时,返回用户态前夕,检查是否存在pending信号,发现有SIGSTOP,于是将自己挂起,并通知gdb;

        7)父进程 将 子进程/子线程 的pid,记录到自己的ptrace_message字段中(后续gdb会来拿这个信息);

        8)父进程发现自己的task->ptrace字段包含了 PTRACE_EVENT_CLONE、PTRACE_EVENT_FORK,代表当前任务的fork、pthread_create动作需要通知gdb,于是调用ptrace_stop,通知父进程并将自己挂起;

        9)gdb被唤醒后,通过wait的status参数得知被调试程序执行了fork、pthread_create动作;

        10)gdb通过ptrace(PTRACE_GETEVENTMSG),陷入内核获取记录在父进程task->ptrace_message中的信息,该信息就是父进程创建的 子进程/子线程 的 pid;

        12)gdb 为 被调试程序创建的 子进程/子线程 创建对应的数据结构,记录在gdb中,至此gdb侧就掌握了被调试程序的所有子线程、子进程相关信息;

        13)最后,gdb通过ptrace(PTRACE_CONT)将被调试程序(父进程)、及其创建的 子进程/子线程 唤醒继续运行;

        14)父进程 以及其创建的 子进程/子线程 被调度继续运行;

三、代码实现

1、gdb为被调试程序设置对应的ptrace字段(告知子进程其哪些动作需要被gdb拦截)

// Case1
linux_process_target::post_create_inferiorlinux_enable_event_reportingsupported_ptrace_options = (PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK| PTRACE_O_TRACEVFORK | PTRACE_O_TRACEVFORKDONE | PTRACE_O_TRACEEXEC)options &= supported_ptrace_optionsptrace(PTRACE_SETOPTIONS, pid, ..., options)flags = task->ptraceflags &= ~(PTRACE_O_MASK << PT_OPT_FLAG_SHIFT)flags |= (options << PT_OPT_FLAG_SHIFT)task->ptrace = flags// Case2
linux_enable_event_reporting (pid_t pid, int options) {if (supported_ptrace_options == -1) {linux_check_ptrace_features() {supported_ptrace_options = (PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK| PTRACE_O_TRACEVFORK | PTRACE_O_TRACEVFORKDONE | PTRACE_O_TRACEEXEC)...}}/* We always want clone events. */options |= PTRACE_O_TRACECLONE/* Filter out unsupported options. */options &= supported_ptrace_optionsptrace(PTRACE_SETOPTIONS, pid, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) (uintptr_t) options) {sys_ptrace(request, pid, addr, data) {ptrace_request(struct task_struct *child, long request, unsigned long addr, unsigned long data) {switch (request)case PTRACE_SETOPTIONS:ptrace_setoptions(child, data) {flags = child->ptraceflags &= ~(PTRACE_O_MASK << PT_OPT_FLAG_SHIFT)flags |= (data << PT_OPT_FLAG_SHIFT)			// 即: flag |= data << 3child->ptrace = flags							// <<<<<< 将 PTRACE_O_TRACEFORK 等event, 设置给目标任务task_struct->ptrace字段}}}}
}

2、父进程执行fork/pthread_create,在内核中的kernel_clone实现

SYSCALL_DEFINE0(fork) {kernel_clone(struct kernel_clone_args *args)int trace = 0u64 clone_flags = args->flags/* Determine whether and which event to report to ptracer. */if (!(clone_flags & CLONE_UNTRACED)) {if (clone_flags & CLONE_VFORK)trace = PTRACE_EVENT_VFORKelse if (args->exit_signal != SIGCHLD)				// pthread_createtrace = PTRACE_EVENT_CLONEelsetrace = PTRACE_EVENT_FORK/******** 判断current是否包含对应trace event *********/ret = ptrace_event_enabled(struct task_struct *task = current, int event = trace) {return task->ptrace & PT_EVENT_FLAG(event)}if (likely(!ret))	trace = 0}struct task_struct *p = copy_process(NULL, trace, NUMA_NO_NODE, args) {p = dup_task_struct(current, node)												// 为新创建的任务生成一个新的task_structptrace_init_task(p, bool ptrace = (clone_flags & CLONE_PTRACE) || trace)		// initialize ptrace state for a new childif (unlikely(ptrace) && current->ptrace)child->ptrace = current->ptrace				/* Set ptrace event to new child task's ptrace, which will be checked later */__ptrace_link(child, current->parent, current->ptracer_cred)sigaddset(&child->pending.signal, SIGSTOP)								// Add SIGSTOP to new task's pending.signal}wake_up_new_task(p)																	// new task will stop when go back to user space a.k.a do_signalif (unlikely(trace)) {	/* forking complete and child started to run, tell ptracer */ptrace_event_pid(event = trace, pid) {message = pid_nr_ns(pid, ns)			/* message: new task's pid. 保存在父进程的task_struct->ptrace_message中 */ptrace_event(event, message)if (unlikely(ptrace_event_enabled(current, event)))current->ptrace_message = messageptrace_notify(exit_code = (event << 8) | SIGTRAP)					// event: PTRACE_EVENT_FORK / PTRACE_EVENT_CLONE / PTRACE_EVENT_VFORKptrace_do_notify(SIGTRAP, exit_code, CLD_TRAPPED)ptrace_stop(exit_code, why, 1, &info)}}
}

3、gdb收集被调试程序fork/pthread_create创建的子进程/子线程信息

linux_process_target::wait_for_event_filtered {	// 3) *** gdb获取子线程/子进程 pid信息 ***/* Always pull all events out of the kernel */while (event_child == NULL) {ret = my_waitpid(wstatp)if (ret > 0) {linux_process_target::filter_event(int lwpid = ret, int wstat = *wstatp) {ret = linux_is_extended_waitstatus (wstat)							// 该函数用于check wait返回后的入参,是否有event事件, 即: PTRACE_EVENT_FORK、PTRACE_EVENT_CLONE 这类事件return (linux_ptrace_get_extended_event (wstat) != 0)return (wstat >> 16)if (WIFSTOPPED (wstat) && WSTOPSIG (wstat) == SIGTRAP && ret) {linux_process_target::handle_extended_wait {int event = linux_ptrace_get_extended_event (wstat)return (wstat >> 16)if ((event == PTRACE_EVENT_FORK) || (event == PTRACE_EVENT_VFORK) || (event == PTRACE_EVENT_CLONE)) {/* Get the pid of the new lwp. */ptrace (PTRACE_GETEVENTMSG, lwpid_of (event_thr), (PTRACE_TYPE_ARG3) 0, &new_pid)*(unsigned long *)data = child->ptrace_messageA.K.A*new_pid = child->ptrace_message				// 获取新的task的pid/* If we haven't already seen the new PID stop, wait for it now.  */if (!pull_pid_from_list (&stopped_pids, new_pid, &status)) {ret = my_waitpid (new_pid, &status, __WALL)}}if (event == PTRACE_EVENT_FORK || event == PTRACE_EVENT_VFORK) {ptid = ptid_t (new_pid, new_pid)/* Add the new process to the tables and clone the breakpoint lists of the parent. */child_proc = add_linux_process (new_pid, 0)child_lwp = add_lwp (ptid)child_lwp->stopped = 1clone_all_breakpoints (child_thr, event_thr)...}}}}/* Retry until nothing comes out of waitpid. */continue}/* Now that we've pulled all events out of the kernel, resume* LWPs that don't have an interesting event to report.  */for_each_thread ([this] (thread_info *thread) {linux_process_target::resume_stopped_resumed_lwps(thread)resume_one_lwp {resume_one_lwp_throw/* 将fork/pthread_create的调用者及新创建的任务重新唤醒 */ptrace (PTRACE_CONT, lwpid_of (thread),...)}}}
}

四、总结

        被调试程序tracee创建新进程/线程时, 会给新任务添加SIGSTOP信号,同时将新创建子任务的pid记录到被调试任务的task->ptrace_message(用于后续gdb通过ptrace GETEVENTMSG来获取新创建任务的pid),然后通过ptrace_stop将自己及新创建的子任务都挂起并通知gdb, 待gdb收集好相关信息后, 会将被调试程序及其创建的子任务再次唤醒。

        至于被调试程序如何知道自己执行fork、pthread_create的时候需要通知gdb,是由gdb通过ptrace(PTRACE_SETOPTIONS)进行设置的。由gdb控制,是否需要跟踪被调试程序创建的子进程、子线程。

        最后,回答下文章开头的几个问题:

        1)被调试程序通过fork/pthread_create创建的子进程/子线程,同样会被gdb跟踪,不过gdb可以控制是否需要跟踪,也可以设置为不跟踪;

        2)在kernel_clone中,会将被调试程序以及其创建的子进程/子线程通过不同方式将其挂起,然后通知gdb;

        3)gdb通过ptrace(PTRACE_GETEVENTMSG)获取子进程/子线程的pid信息;

相关文章:

linux ptrace 图文详解(八) gdb跟踪被调试程序的子线程、子进程

目录 一、gdb跟踪被调试程序的fork、pthread_create操作 二、实现原理 三、代码实现 四、总结 &#xff08;代码&#xff1a;linux 6.3.1&#xff0c;架构&#xff1a;arm64&#xff09; One look is worth a thousand words. —— Tess Flanders 相关链接&#xff1a; …...

【列表类型】

1、按索引取值 索引可正向存取&#xff0c;也可反向存取 l [111, paipai, cat] # 正向取值 print(l[1]) # 方向取值 print(l[-1]) # 通过索引给列表重新赋值,前提&#xff1a;索引存在 l[0] ccat print(l) # 索引不存在的情况下&#xff0c;取值or重新赋值的情况下都会报错 …...

MySQL 8.0 OCP 英文题库解析(二)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到2025.07.31 之前。所有人均可以免费考取 原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题6~15。 试题6: …...

数据分析与逻辑思维:六步解决业务难题;参考书籍《数据分析原理:6步解决业务分析难题 (周文全, 黄怡媛, 马炯雄)》

文章目录 一、懂业务&#xff1a;业务背景与逻辑前提1.1 明确业务目标与问题定义1.2 培养批判性思维与高于业务视角 二、定指标&#xff1a;构建科学的指标体系2.1 指标拆解与维度分析2.2 典型指标体系案例&#xff1a;用户与业务视角 三、选方法&#xff1a;匹配业务需求的分析…...

人力资源管理系统如何有效提高招聘效率?

在传统招聘模式下&#xff0c;企业招聘常常陷入 “泥潭”。HR 每天需要花费大量时间在海量简历中 “大海捞针”&#xff0c;手动筛选、电话沟通、安排面试&#xff0c;流程繁琐且效率低下。好不容易邀约到候选人&#xff0c;却因面试安排冲突、信息传递不及时等问题&#xff0c…...

FAISS 与机器学习、NLP 的关系

FAISS&#xff08;Facebook AI Similarity Search&#xff09;是一个用于高效相似性搜索和密集向量聚类的开源库&#xff0c;由 Facebook AI Research 开发。它在机器学习&#xff08;特别是自然语言处理&#xff0c;NLP&#xff09;领域中扮演着重要角色&#xff0c;主要解决大…...

文件包含2

远程文件包含与本地文件包含的区别 对比 对比项本地文件包含&#xff08;LFI&#xff09;远程文件包含&#xff08;RFI&#xff09;定义攻击者包含服务器本地的文件攻击者包含远程服务器&#xff08;如HTTP/FTP&#xff09;上的文件依赖条件不需要特殊配置需要allow_url_incl…...

嵌入式系统架构验证工具:AADL Inspector v1.10 全新升级

软件架构建模与早期验证是嵌入式应用的关键环节。架构分析与设计语言&#xff08;AADL&#xff09;是专为应用软件及执行平台架构模型设计的语言&#xff0c;兼具文本与图形化的双重特性。AADL Inspector是一款轻量级的独立工具&#xff1a; 核心处理能力包括 √ 支持处理AA…...

软考高级系统架构设计师备考分享:操作系统核心知识点整理

在备战软考高级系统架构设计师的过程中&#xff0c;操作系统作为核心考点之一&#xff0c;需要系统性地掌握其核心原理。本文将从操作系统分类、进程状态模型、同步互斥机制、死锁问题及存储管理五大模块展开梳理&#xff0c;结合考试高频考点和实际案例进行解析。 一、操作系统…...

22、城堡防御工事——React 19 错误边界与监控

一、魔法护盾&#xff1a;错误边界机制 1. 城墙结界&#xff08;Error Boundary&#xff09; // 客户端错误边界use client function useErrorBoundary() {const [error, setError] useState(null);​const handleError useCallback((error, errorInfo) > {setError(erro…...

有关SOA和SpringCloud的区别

目录 1. 定义 2. 架构风格 3. 技术栈 4. 服务交互 5. 适用场景 前言 面向服务架构&#xff08;SOA&#xff09;是一种软件设计风格&#xff0c;它将应用程序的功能划分为一系列松散耦合的服务。这些服务可以通过标准的通信协议进行交互&#xff0c;通常是HTTP或其他消息传…...

大数据——Mac环境DataSpell集成Jupyter

1、设置 2、添加新的解释器 3、解释器类型选择Conda 4、进入选中全部&#xff0c;然后重启 5、dataspell右下角会显示当前项目的运行环境 6、创建Jupyter Notebook文件 7、测试 8、查看当前配置 &#xff08;1&#xff09;本地模式安装使用 &#xff08;2&#xff09;…...

解锁健康养生新境界

在追求高品质生活的当下&#xff0c;健康养生早已超越 “治未病” 的传统认知&#xff0c;成为贯穿全生命周期的生活艺术。它如同精密的交响乐&#xff0c;需饮食、运动、心理与生活习惯多维度协奏&#xff0c;方能奏响生命的强音。 饮食养生讲究 “顺时、适性”。遵循二十四节…...

WORD压缩两个免费方法

日常办公和学习中&#xff0c;Word文档常常因为包含大量图片、图表或复杂格式而导致文件体积过大&#xff0c;带来诸多不便&#xff0c;比如 邮件发送受限&#xff1a;许多邮箱附件限制在10-25MB&#xff0c;大文件无法直接发送 存储空间占用&#xff1a;大量文档占用硬盘或云…...

Zabbix监控 RabbitMQ 指定消息队列名称(pull_alarms )的消费者

✅ 1. 编写 RabbitMQ 队列监控脚本 创建脚本文件 /usr/local/bin/zbx_rabbitmq_metric.sh 并写入以下内容&#xff1a; #!/bin/bash # /usr/local/bin/zbx_rabbitmq_metric.shQUEUE$1 METRIC$2 USER$3 PASS$4if [[ -z "$QUEUE" || -z "$METRIC" || -z &q…...

RabbitMQ ②-工作模式

RabbitMQ 工作模式 官方提供了七种工作模式 Simple&#xff08;简单模式&#xff09; P&#xff1a;生产者&#xff0c;发布消息到队列C&#xff1a;消费者&#xff0c;从队列中获取消息并消费Queue&#xff1a;消息队列&#xff0c;存储消息。 一个生产者&#xff0c;一个…...

《探索React Native社交应用中WebRTC实现低延迟音视频通话的奥秘》

WebRTC&#xff0c;全称为Web Real-Time Communication&#xff0c;是一项开创性的开源技术&#xff0c;为Web和移动应用开启了实时通信的大门。它打破了传统通信的束缚&#xff0c;使得应用之间无需依赖繁琐的中间服务器&#xff0c;就能实现直接的点对点通信&#xff0c;这是…...

UI设计公司兰亭妙微分享:汽车 MHI 设计的界面布局创新法则

在汽车人机界面&#xff08;MHI&#xff09;设计中&#xff0c;界面布局犹如建筑蓝图&#xff0c;奠定了用户与汽车交互体验的基础。合理创新的布局能提升驾驶安全性与便捷性&#xff0c;融合极简美学与高效操作则成为现代汽车 MHI 界面布局设计的核心追求。​ 驾驶场景中&…...

【递归,搜索与回溯算法篇】专题(一) - 递归

文章目录 面试题 08.06. 汉诺塔问题21. 合并两个有序链表206. 反转链表24. 两两交换链表中的节点50. Pow(x, n) 面试题 08.06. 汉诺塔问题 题目链接&#xff1a; 面试题 08.06. 汉诺塔问题 题目描述&#xff1a; 在经典汉诺塔问题中&#xff0c;有 3 根柱子及 N 个不同大小的…...

B站pwn教程笔记-9

前言&#xff1a;可以去一些开源镜像站下载libc老的乌班图镜像&#xff0c;因为堆题的libc可能比较老&#xff0c;没有新的一些保护措施和机制。 格式化字符串漏洞 归根结底&#xff0c;可以读写任意地址内存。 泄露栈数据/任意地址数据 主要问题就是printf不知道自己有没有…...

NVR(网络视频录像机) 和 网络摄像机(IPC,IP Camera)

NVR&#xff08;网络视频录像机&#xff09; 和 网络摄像机&#xff08;IPC&#xff0c;IP Camera&#xff09; 是网络监控系统的两个核心组件&#xff0c;但功能定位完全不同。以下是它们的核心区别&#xff1a; 1. 功能角色 组件网络摄像机&#xff08;IPC&#xff09;NVR&a…...

数智读书笔记系列032《统一星型模型--一种敏捷灵活的数据仓库和分析设计方法》

引言 在当今数字化时代,数据仓库作为企业数据管理的核心基础设施,承担着整合、存储和提供企业数据的关键角色。随着商业环境的快速变化和业务需求的日益复杂,数据仓库的设计方法也在不断演进,以适应新的挑战和要求。 背景与意义 数据仓库领域长期存在着两种主流方法论之…...

互联网大厂Java求职面试:基于RAG的智能问答系统设计与实现

互联网大厂Java求职面试&#xff1a;基于RAG的智能问答系统设计与实现 场景背景 在某互联网大厂的技术面试中&#xff0c;技术总监张总正在面试一位名为郑薪苦的求职者。郑薪苦虽然对技术充满热情&#xff0c;但回答问题时总是带着幽默感&#xff0c;有时甚至让人哭笑不得。 …...

[C#]Task.Run()和Task.Factory.StartNew()对比(腾讯元宝)

Task.Run和Task.Factory.StartNew都是用来创建并启动任务的方法&#xff0c;但它们的内部实现和使用场景有所不同。两者的主要区别&#xff1a;默认调度器、配置选项、异常处理、适用场景。建议用户大多数情况下使用Task.Run&#xff0c;除非需要StartNew的高级配置&#xff0c…...

Java游戏服务器开发流水账(3)游戏数据的缓存简介

简介 游戏服务器数据缓存是一种在游戏服务器运行过程中&#xff0c;用于临时存储经常访问的数据的技术手段&#xff0c;旨在提高游戏性能、降低数据库负载以及优化玩家体验。游戏开发中数据的缓存可以使用Java自身的内存也可以使用MemCache&#xff0c;Redis&#xff0c;注意M…...

PostgreSQL可见性映射VM

1.可见性映射 清理过程的代价高昂&#xff0c;为了减小清理的开销&#xff0c;在PostgreSQL 8.4版中引入了VM。 VM的基本概念很简单。 每个表都拥有各自的可见性映射&#xff0c;用于保存表文件中每个页面的可见性。 页面的可见性确定了每个页面是否包含死元组。清理过程可以…...

集成电路流片随笔26:tinyriscv的三级流水线细则pc

include "defines.v"// PC寄存器模块 module pc_reg(input wire clk,input wire rst,input wire jump_flag_i, // 跳转标志input wire[InstAddrBus] jump_addr_i, // 跳转地址input wire[Hold_Flag_Bus] hold_flag_i, // 流水线暂停标志input wire…...

如何解决Jmeter中的乱码问题?

在 JMeter 中遇到乱码问题通常是由于字符编码不一致导致的&#xff0c;常见于 HTTP 请求响应、参数化文件读取、报告生成等场景。以下是系统化的解决方案&#xff1a; 1. HTTP 请求响应乱码 原因&#xff1a; 服务器返回的字符编码&#xff08;如UTF-8、GBK&#xff09;与 J…...

TextRNN 模型实现微博文本情感分类

在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;文本情感分类是一项极具应用价值的任务。它能帮助企业分析用户反馈、社交媒体舆情监测等。本文将通过一段实际代码&#xff0c;带大家了解如何利用 PyTorch 框架和 TextRNN 模型&#xff0c;完成微博文本的情感分类工…...

支付宝 SEO 优化:提升小程序曝光与流量的完整指南

在拥有庞大用户基数的支付宝平台上&#xff0c;小程序已成为商家触达用户、提供服务的重要渠道。然而&#xff0c;随着平台上小程序数量的快速增长&#xff0c;如何在激烈的竞争中脱颖而出&#xff0c;获得更多的曝光和流量&#xff0c;成为每个开发者和运营者必须面对的关键挑…...

基于WSL用MSVC编译ffmpeg7.1

在windows平台编译FFmpeg&#xff0c;网上的大部分资料都是推荐用msys2mingw进行编译。在win10平台&#xff0c;我们可以采用另一种方式&#xff0c;即wslmsvc 实现window平台的ffmpeg编译。 下面将以vs2022ubuntu22.04 为例&#xff0c;介绍此方法 0、前期准备 安装vs2022 &…...

高并发内存池(二):项目的整体框架以及Thread_Cache的结构设计

目录 前言 一&#xff0c;项目整体框架设计 二&#xff0c;thread cache结构设计 模拟定长内存池的设计思路 采用一定的对齐规则设计 thread cache大致框架 申请内存Allocate方法 1&#xff0c;thread cache 哈希桶的内存对齐规则 2&#xff0c;内存对齐规则代码实现 …...

K8S扩缩容及滚动更新和回滚

目录&#xff1a; 1、滚动更新1、定义Deployment配置2、应用更新 2、版本回滚1. 使用kubectl rollout undo命令 3、更新暂停与恢复1、暂停更新2、更新镜像&#xff08;例如&#xff0c;使用kubectl set image命令&#xff09;3、恢复更新 4、弹性扩缩容1、扩容命令2、缩容命令3…...

K8S - GitLab CI 自动化构建镜像入门

一、引言 在现代持续交付&#xff08;CI/CD&#xff09;体系中&#xff0c;容器镜像的自动化构建与推送已成为交付链条的重要一环。 GitLab CI/CD 作为 GitLab 平台的原生集成功能&#xff0c;提供了声明式、可扩展的流水线机制&#xff0c;使得开发者可以在代码生命周期内实…...

万兴PDF-PDFelement v11.4.13.3417

万兴PDF专家(Wondershare PDFelement)是一款国产PDF文档全方位解决方案.万兴PDF编辑器软件万兴PDF中文版,专注于PDF的创建,编辑,转换,签名,压缩,合并,比较等功能.万兴PDF专业版PDF编辑软件,以简约风格及强大的功能在国外名声大噪,除了传统功能外,还提供OCR扫描,表格识别,创建笔…...

4.2【LLaMA-Factory实战】金融财报分析系统:从数据到部署的全流程实践

【LLaMA-Factory实战】金融财报分析系统&#xff1a;从数据到部署的全流程实践 一、引言 在金融领域&#xff0c;财报分析是投资决策的核心环节。传统分析方法面临信息提取效率低、风险识别不全面等挑战。本文基于LLaMA-Factory框架&#xff0c;详细介绍如何构建一个专业的金…...

Vue Router 3 使用详解:从零构建嵌套路由页面

Vue Router 是 Vue.js 官方的路由管理器&#xff0c;常用于构建单页面应用&#xff08;SPA&#xff09;。本文将手把手带你完成 vue-router3.6.5 的基本配置&#xff0c;并实现一个带有嵌套路由的页面结构。本文适用于 Vue 2.x 项目 一、安装 vue-router3.6.5 npm install vue…...

ChatGPT深度研究功能革新:GitHub直连与强化微调

目录 一、ChatGPT深度研究功能迎来革命性更新 1.1 GitHub直连功能详解 1.2 强化微调(RTF)正式发布 二、GitHub直连功能深度体验 2.1 实际应用场景演示 2.2 技术实现原理探讨 三、强化微调技术解析 3.1 RTF技术核心优势 3.2 适用场景分析 四、开发者反馈与行业影响 4…...

【Ansible】模块详解

一、ansible概述 1.1 ansible介绍 Ansible 是一个基于 Python 开发的配置管理和应用部署工具&#xff0c;近年来在自动化管理领域表现突出。它集成了许多传统运维工具的优点&#xff0c;几乎可以实现 Pubbet 和 Saltstack 所具备的功能。 1.2 ansible能做什么 批量处理。An…...

深入理解C/C++内存管理:从基础到高级优化实践

一、内存区域划分与基础管理机制​​ ​​栈&#xff08;Stack&#xff09;​​ 栈由系统自动管理&#xff0c;用于存储函数调用时的局部变量、参数及返回地址。其特点是高效但空间有限&#xff08;通常1-8MB&#xff09;&#xff0c;遵循后进先出&#xff08;LIFO&#xff09;…...

两台服务器之前共享文件夹

本文环境 服务器A:ubuntu24.22系统 IP:10.0.8.1 服务器B:ubuntu24.22系统 IP:10.0.8.10 本操作旨在将服务器B的/opt/files目录共享给服务器A得/opt/files 在 B 服务器上设置共享 安装 NFS 服务&#xff1a; sudo apt -y install nfs-kernel-server编辑/etc/exports文件&…...

stm32之USART

目录 1.引入1.1 通信接口1.2 串口 2.USART2.1 简介2.2 框图2.3 基本机构图2.4 数据帧2.5 波特率发生器2.6 数据包2.6.1 数据模式2.6.2 HEX数据包2.6.3 文本数据包2.6.4 HEX数据包接收2.6.5 文本数据包接收 3.结构体和相关API3.1 结构体3.2 API3.2.1 **初始化相关函数**void USA…...

使用 systemd 管理 Linux 服务:配置与自动重启指南

使用 systemd (推荐&#xff0c;适用于大多数 Linux 发行版) systemd 是现代 Linux 系统中最常用的服务管理器。它能可靠地管理进程&#xff0c;并在进程崩溃时自动重启。 创建 systemd 服务文件&#xff1a; 创建一个文件&#xff0c;例如 /etc/systemd/system/app.service…...

【计算机视觉】Car-Plate-Detection-OpenCV-TesseractOCR:车牌检测与识别

Car-Plate-Detection-OpenCV-TesseractOCR&#xff1a;车牌检测与识别技术深度解析 在计算机视觉领域&#xff0c;车牌检测与识别&#xff08;License Plate Detection and Recognition, LPDR&#xff09;是一个极具实用价值的研究方向&#xff0c;广泛应用于智能交通系统、安…...

《Spring Boot 3.0全新特性详解与实战案例》

大家好呀&#xff01;今天让我们轻松掌握Spring Boot 3.0的所有新特性&#xff01;&#x1f680; &#x1f4cc; 第一章&#xff1a;Spring Boot 3.0简介 1.1 什么是Spring Boot 3.0&#xff1f; Spring Boot 3.0就像是Java开发者的"超级工具箱"&#x1f9f0;&…...

二叉树的深度

二叉树的深度是指从根节点到叶子节点的最长路径上的节点数。 一、最大深度 104. 二叉树的最大深度 - 力扣&#xff08;LeetCode&#xff09; 最大深度是指从根节点到最远叶子节点的最长路径上的节点数。 //递归法 /*** Definition for a binary tree node.* public class T…...

科技创业园共享会议室线上预约及智能密码锁系统搭建指南

为科技创业园区的运营管理者&#xff0c;我深知高效利用会议室资源的重要性。2023年第三季度&#xff0c;我们园区启动会议室智能化改造项目&#xff0c;经过三个月的实践&#xff0c;成功将32间共享会议室升级为"线上预约智能门锁"管理模式。现将改造经验分享如下&a…...

自定义prometheus exporter实现监控阿里云RDS

# 自定义 Prometheus Exporter 实现多 RDS 数据采集## 背景1. Prometheus 官网提供的 MySQL Exporter 对于 MySQL 实例只能一个进程监控一个实例&#xff0c;数据库实例很多的情况下&#xff0c;不方便管理。 2. 内部有定制化监控需求&#xff0c;RDS 默认无法实现&#xff0c;…...

LeetCode 3342.到达最后一个房间的最少时间 II:dijkstra算法(和I一样)

【LetMeFly】3342.到达最后一个房间的最少时间 II&#xff1a;dijkstra算法(和I一样) 力扣题目链接&#xff1a;https://leetcode.cn/problems/find-minimum-time-to-reach-last-room-ii/ 有一个地窖&#xff0c;地窖中有 n x m 个房间&#xff0c;它们呈网格状排布。 给你一…...

iOS创建Certificate证书、制作p12证书流程

一、创建Certificates 1、第一步得先在苹果电脑上创建一个.certSigningRequest的文件。首先打开钥匙串&#xff0c;使用快捷键【command空格】——输入【钥匙串】回车&#xff08;找不到就搜一下钥匙串访问使用手册&#xff09; 2、然后在苹果电脑的左上角菜单栏选择【钥匙串…...