Linux内核之tracepoint介绍

概述

Tracepoint 是一种在 Linux 内核中插入的静态探测点,用于跟踪和调试内核行为。它允许开发者在特定位置插入代码,收集运行时信息,而不会显著影响性能。

原理

特性

  • 静态探测点: 在内核预定义, 自定义的函数可以插入在这里
  • 动态启用: 默认不启用, 减少性能开销
  • 低开销
阅读更多

bpftrace简介

概述

bpftrace是一个基于eBPF的高级跟踪工具, 用于动态追踪Linux系统的行为和性能.

用于可以用简单的一行命令或者简洁的脚本,实现监控分析内核和用户空间程序的运行,而无需修改或者重新编译

安装

sudo apt-get install bpftrace
阅读更多

Redis IO线程介绍

引言

在当今数据驱动的应用开发领域,高性能的数据存储和处理系统至关重要。Redis 作为一款广泛使用的内存数据库,其出色的性能在很大程度上得益于高效的 I/O 处理机制,而 Redis IO 线程则是这一机制的核心组成部分。

Redis IO 线程介绍

基本概念

Redis 是基于事件驱动的单线程模型,早期版本中,Redis 服务器在一个线程内处理所有的网络 I/O、命令处理和数据存储等操作。随着数据量和并发请求的增加,单线程模型在处理大量 I/O 操作时逐渐成为性能瓶颈。为了突破这一限制,Redis 引入了 I/O 多线程机制。

阅读更多

Linux bridge配置工具介绍:bridge-utils与iproute2

概述

bridge-utils 是一个用于管理和配置 Linux 桥接设备的工具集。它提供了一组命令行工具(如 brctl),用于创建、管理和监控 Linux 桥接设备。

iproute2 是一个功能强大的 Linux 网络配置工具集,用于管理和配置现代 Linux 内核中的网络功能。它取代了传统的 net-tools 工具集(如 ifconfigroutearp 等),提供了更强大、更灵活的网络管理功能。

iproute2 的核心命令是 ip,它能够管理网络接口、路由、策略路由、邻居(ARP)、隧道、VLAN、桥接、流量控制等。

安装

阅读更多

网络设备介绍之交换机

概述

在交换机出现之前,局域网内的设备使用集线器连接

当局域网中某个设备发送数据的时候,需要确保其他设备没有发送数据,因为所有设备都在同一个冲突域上

交换机的发明就是解决这个问题

交换机可以划分冲突域,交换机的不同端口设备发送数据不会冲突;这得益于交换机的设计:

阅读更多

Redis 持久化介绍

概述

持久性指的是将数据写入持久存储,例如固态硬盘(SSD)。Redis 提供了一系列持久化选项。这些包括:

  • RDB(Redis Database):RDB 持久化在指定的时间间隔内对您的数据集执行点时间快照。
  • AOF (Append Only File) : AOF 持久化记录服务器接收到的每个写操作。这些操作可以在服务器启动时再次回放,重建原始数据集。命令使用与 Redis 协议相同的格式进行记录。
  • 无持久性:您可以完全禁用持久性。这有时用于缓存。
  • RDB + AOF:您还可以在同一实例中同时使用 AOF 和 RDB。

RDB

RDB创建数据集的快照

阅读更多

动态链接库的基本介绍

ld.so

ld.so的路径存在于任意一个存在动态链接库的elf文件上的.interp setion中

# objdump -s -j .interp /bin/ls
/bin/ls: file format elf64-x86-64

Contents of section .interp:
02a8 2f6c6962 36342f6c 642d6c69 6e75782d /lib64/ld-linux-
02b8 7838362d 36342e73 6f2e3200 x86-64.so.2.

#readelf -a /bin/ls | grep 'interpreter'
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]

任何动态链接的程序都需要ld.so去启动,即直接执行一个动态链接库程序等价于执行 ld.so <program>

调试

阅读更多

wsl常见问题解决

更改wsl虚拟磁盘位置

默认虚拟磁盘文件大体是在C:\Users\XXX\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu24.04LTS_79rhkp1fndgsc\LocalState (以ubuntu2404为例)

将里面的vhdx移动到目标盘位置,比如 D:\wsl\24.04\ , 然后执行命令即可

wsl --unregister Ubuntu-24.04
wsl --import-in-place Ubuntu-24.04 "D:\wsl\24.04\ext4.vhdx”

压缩磁盘

阅读更多

golang运行时源码解读-Goroutine

前言

Goroutine 是 Go 语言的并发执行单元,是Go语言并发的基础。本文将从源码的角度,解读Goroutine的创建、销毁、状态转移等过程。

协程数据结构

type g struct {
// 栈参数。
// stack 描述了实际的栈内存:[stack.lo, stack.hi)。
// stackguard0 是在 Go 栈增长序言中比较的栈指针。
// 它通常是 stack.lo+StackGuard,但可以是 StackPreempt 以触发抢占。
// stackguard1 是在 //go:systemstack 栈增长序言中比较的栈指针。
// 它在 g0 和 gsignal 栈上是 stack.lo+StackGuard。
// 在其他协程栈上是 ~0,以触发对 morestackc 的调用(并崩溃)。
stack stack // 偏移量已知 runtime/cgo
stackguard0 uintptr // 偏移量已知 liblink
stackguard1 uintptr // 偏移量已知 liblink

_panic *_panic // 最内层的 panic - 偏移量已知 liblink
_defer *_defer // 最内层的 defer
m *m // 当前执行的 m; 偏移量已知 arm liblink
sched gobuf // 调度相关信息
syscallsp uintptr // 如果 status==Gsyscall,syscallsp = sched.sp 用于 gc
syscallpc uintptr // 如果 status==Gsyscall,syscallpc = sched.pc 用于 gc
syscallbp uintptr // 如果 status==Gsyscall,syscallbp = sched.bp 用于 fpTraceback
stktopsp uintptr // 栈顶的预期 sp,用于 traceback 检查
// param 是一个通用指针参数字段,用于在特定上下文中传递值,
// 这些上下文中找到其他存储参数的地方会很困难。它目前有四种用法:
// 1. 当一个通道操作唤醒一个阻塞的协程时,它将 param 设置为指向已完成的阻塞操作的 sudog。
// 2. 由 gcAssistAlloc1 用于向其调用者发信号,表明协程完成了 GC 周期。以其他方式这样做是不安全的,因为协程的栈可能在此期间已移动。
// 3. 由 debugCallWrap 用于将参数传递给一个新的协程,因为在运行时分配闭包是被禁止的。
// 4. 当一个 panic 被恢复并且控制返回到相应的帧时,param 可能指向一个 savedOpenDeferState。
param unsafe.Pointer
atomicstatus atomic.Uint32
stackLock uint32 // sigprof/scang 锁;TODO: 合并到 atomicstatus
goid uint64
schedlink guintptr
waitsince int64 // 大约阻塞的时间
waitreason waitReason // 如果 status==Gwaiting

preempt bool // 抢占信号,重复 stackguard0 = stackpreempt
preemptStop bool // 在抢占时转换为 _Gpreempted;否则,只是取消调度
preemptShrink bool // 在同步安全点缩小栈

// asyncSafePoint 表示 g 是否在异步安全点停止。这意味着栈上有没有精确指针信息的帧。
asyncSafePoint bool

paniconfault bool // 在意外的故障地址上 panic(而不是崩溃)
gcscandone bool // g 已扫描栈;受 status 中的 _Gscan 位保护
throwsplit bool // 不得分割栈
// activeStackChans 表示是否有未锁定的通道指向此协程的栈。如果为 true,栈复制需要获取通道锁以保护这些栈区域。
activeStackChans bool
// parkingOnChan 表示协程即将停放在 chansend 或 chanrecv 上。用于在栈缩小时发出不安全点信号。
parkingOnChan atomic.Bool
// inMarkAssist 表示协程是否在标记辅助中。由执行跟踪器使用。
inMarkAssist bool
coroexit bool // 协程切换时的参数

raceignore int8 // 忽略竞争检测事件
nocgocallback bool // 是否禁用从 C 回调
tracking bool // 是否跟踪此 G 的调度延迟统计
trackingSeq uint8 // 用于决定是否跟踪此 G
trackingStamp int64 // G 最后一次开始被跟踪的时间戳
runnableTime int64 // 可运行时间,在运行时清除,仅在跟踪时使用
lockedm muintptr
sig uint32
writebuf []byte
sigcode0 uintptr
sigcode1 uintptr
sigpc uintptr
parentGoid uint64 // 创建此协程的协程的 goid
gopc uintptr // 创建此协程的 go 语句的 pc
ancestors *[]ancestorInfo // 创建此协程的祖先协程信息(仅在 debug.tracebackancestors 时使用)
startpc uintptr // 协程函数的 pc
racectx uintptr
waiting *sudog // 此 g 正在等待的 sudog 结构(具有有效的 elem 指针);按锁顺序排列
cgoCtxt []uintptr // cgo 回溯上下文
labels unsafe.Pointer // 分析器标签
timer *timer // 缓存的 time.Sleep 定时器
sleepWhen int64 // 何时休眠
selectDone atomic.Uint32 // 我们是否参与了 select 并且有人赢得了比赛

// goroutineProfiled 表示此协程的栈在当前进行中的协程分析中的状态
goroutineProfiled goroutineProfileStateHolder

coroarg *coro // 协程切换期间的参数

// 每个 G 的跟踪器状态。
trace gTraceState

// 每个 G 的 GC 状态

// gcAssistBytes 是此 G 的 GC 辅助信用,以分配的字节数表示。如果这是正数,则 G 有信用可以分配 gcAssistBytes 字节而无需辅助。如果这是负数,则 G 必须通过执行扫描工作来纠正此问题。我们以字节为单位跟踪这个,以便在 malloc 热路径中快速更新和检查债务。辅助比率决定了这与扫描工作债务的对应关系。
gcAssistBytes int64
}

协程的创建

阅读更多