- 博客(41)
- 资源 (3)
- 收藏
- 关注
原创 申明glibc的引用版本
glibc通过兼容符号,允许glibc和静态链接器(编译时候的链接器)从不通版本的函数中选择一个实现。动态链接器(程序执行时的链接器)会根据ELF文件中链接的版本进行链接。最新的更改是2.34因此会将编译时链接器会将@@替换为@@GLIBC_2.34,该 URL 存储在程序的动态元件表中。的符号,如果没有指定@@ 则为最新版本,在C语言程序中链接过程中,搜索以。
2025-01-07 13:58:58
196
原创 XFS寻址模拟
因此log 的block 会在 1000000000000000000110 / 2^18=8 的1000000000000000000110%2^18=3 偏移 ,即日志在AG7 的 第三个block开始。XFS默认会支持64位地址,但是一般小于2T会折叠上32位,日志的起始为0x200006 agblklog = 18(XFS 大部分时候都会用绝对地址,即包含AG信息和相对AG偏移量的信息,但有些时候会使用相对地址“相对AG的偏移量”再来计算一个文件,通过文件查询BMAP来找到对应的bloc。
2024-08-07 03:41:18
280
原创 XFS超级块介绍-xfs_sb
使用16进制进行查询是原始且酷酷的,同样的,另一种快速查看的方法是使用xfs_db ,用xfs_db可以自动化的将16进制的内容打印出来,“xfs_db -r” 允许对挂载的文件系统进行只读访问。同时文件系统AG的数量(88-91)和每个AG块的大小(84-87)是很重的,XFS通过AG去索引数据在物理磁盘的位置,上面截图的文件系统有16(0x10)个AG每个AG的block的数量为163840(0x28000) 这样文件系统的大小就是AG数量*AG大小=10GB。超级块的具体内容可以参考内核的。
2024-08-07 01:49:12
514
原创 模拟一次XFS故障,分析原因并进行修复
在平常处理问题时经常会遇到文件系统损坏的问题,有时候是日志里面出现了报错但文件系统还是可以读写,有时候是文件系统已经无法读写了分析下不同现象的原因和一些可能出现的情况。
2024-08-06 15:00:58
1297
原创 通过systemd-resloved实现不同域名通过不同的`nameserver`进行解析
一般来说只要DNS不发生网络故障就只会在一个 获取地址,但我们可能需要从不同 获取不同域名的地址,比如内网环境和外网环境分别使用不同的 ,但resloveconf只会在一个DNS server获取地址,即使在中设置了多个 如果第一个 返回的是而不是没有返回也不会使用其他的如果需要按照匹配进行查询可以参考以下步骤编辑systemd-resloved /etc/systemd/resolved.conf.d/custom.conf 指定Domains=www.test.com 到其他地方进行解析查看当前配置可
2024-08-04 17:19:46
1317
原创 生成特定架构内核cscope数据库
tags代码浏览工具tags工具介绍一般来说,如果我们想要研究一个c/c++项目的源码,我们首先要做的是为该项目生成tags文件,tags文件种类有很多,比如 ctags、etags、cscope、gtags 等,有关他们的区别可以参考下面链接里的内容:https://github.com/oracle/opengrok/wiki/Comparison-with-Similar-Toolsctags使用ctags官网提供下载,安装、手册、FAQ等信息http://ctags.sourcefor
2022-04-19 13:28:38
990
2
原创 UEFI引导过程
EFI引导最近遇到的很多问题都和UEFI启动,调研了下UEFI的启动流程一般认为,UEFI由以下几个部分组成:BIOS自检 Pown On 阶段 这一阶段从上电开始到屏幕出现信息结束,也就是所谓的激活电源阶段。主板上的控制芯片组会向CPU发出并保持一个RESET(重置)信号,让CPU内部自动恢复到初始状态,但CPU在此刻不会马上执行指令。当芯片组检测到电源已经开始稳定供电了这一阶段的主要任务是校验CMOS中的内容是否正确、检查主机上某些硬件的状态以确定下一步的自检,因此,用户无法在屏幕上看
2022-03-24 09:35:44
8747
原创 基于内核秘钥保留服务的ELF文件签名程序和验签模块
基于内核秘钥保留服务的ELF文件签名程序和验签模块解决方案的核心思想是,以 二进制文件处理程序 的形式,实现一个 ELF 签名验证模块 (binfmt_elf_signature_verification),并将该模块注册到链表中 ELF 处理模块 (binfmt_elf) 之前。在该模块中,实现签名验证的逻辑。如果签名验证通过,则返回 -ENOEXEC 错误码,使得内核能够继续遍历链表,直到调用真正的 ELF 处理模块;如果签名验证不通过,则直接返回其它错误码,使得内核不再继续调用真正的 ELF 处理模
2022-03-21 10:57:51
2165
原创 GDB调试基础
GDB调试1.1 基础的调试快捷键s step,si步入n 执行下一条指令 ni步入b 在某处下断点,可以用b * adrressb function_nameinfo b 查看断点信息delete 1删除第一个断点c 继续r 执行disas addr 查看addr处前后的反汇编代码1.2 显示数据p 系列p system/main 显示某个函数地址p $esp 显示寄存器p/x p/a p/b p/s。。。p 0xff - 0xea 计算器print
2022-03-14 14:45:25
605
原创 内核trace框架
Linux内核trace 从广义上讲,linux中的跟踪系统由三层组成:前端、跟踪框架和事件源 事件源是跟踪数据的来源,跟踪框架运行在负责数据收集、计数的内核中,如果它支持内核编程跟踪程序(例如:eBPF),它还以有效的方式执行聚合、汇总和统计。跟踪前端工具提供了与跟踪框架通信的用户界面,使用后处理跟踪器(如果有)进行统计、汇总和聚合采样,并向最终用户进行结果可视化。术语性能分析:性能分析的目的是为了获取跟踪事件的样本跟踪:跟踪记录所有的trace事件探针:动态或者静态代码中的一种插装
2022-03-14 14:42:19
3739
原创 堆内存(8)——内存释放函数_int_free
_int_free 在_lib_free中得知如果一个chunk不是由mmap分配得到,就会调用_int_free进行释放。void __libc_free(void *mem) {...p = mem2chunk(mem);if (chunk_is_mmapped(p)){ ...}ar_ptr = arena_for_chunk(p);_int_free(ar_ptr, p, 0);}第一部分static void_int_free (mstate av, mch
2022-03-14 09:41:50
1894
原创 堆内存(7)——内存释放入口函数_lib_free
_libc_freevoid__libc_free (void *mem){ mstate ar_ptr; mchunkptr p; /* chunk corresponding to mem */ void (*hook) (void *, const void *) = atomic_forced_read (__free_hook); if (__builtin_expect (hook != NULL, 0))
2022-03-11 09:41:38
679
原创 堆内存(6)——MORECORE宏
MORECORE宏MORECORE是一个宏定义,其最终是通过系统调用分配内存,定义在linux内核的mmap.c文件中,SYSCALL_DEFINE1(brk, unsigned long, brk){ unsigned long retval; unsigned long newbrk, oldbrk; struct mm_struct *mm = current->mm; unsigned long min_brk; bool populate;
2022-03-11 09:40:22
421
原创 堆内存(5)——系统调用MMAP、MUMAP
MMAPmmap 声明mmap/munmap函数声明如下:#include <sys/mman.h>void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);int munmap(void *addr, size_t length);addr:如果不为NULL,内核会在此地址创建映射;否则,内核会选择一个合适的虚拟地址。length:表示映
2022-03-11 09:39:14
2001
原创 堆内存(4)——向操作系统申请内存sysmalloc
向操作系统申请内存sysmallocsysmalloc流程图尝试mmap分配try_mmap如果空间用完static void * sysmalloc(INTERNAL_SIZE_T nb, mstate av) { //声明结构体 ..... if (av == NULL || ((unsigned long) (nb) >= (unsigned long) (mp_.mmap_threshold) && (mp_
2022-03-11 09:36:21
1903
原创 堆内存(3)——分配函数_int_malloc
_int_malloc__libc_malloc会调用malloc_hook_ini 进行初始化,然后回调__libc_malloc函数,这时候会执行_int_malloc开始分配内存//堆内存分配入口函数static void *_int_malloc (mstate av, size_t bytes){ ...... //将内存转换以块为单位,并判断内存大小是否合法 if (!checked_request2size (bytes, &nb)) {
2022-03-11 09:34:00
1845
原创 堆内存(2) ——分配入口__lib_malloc
__libc_mallocmalloc的入口函数为__libc_malloc其流程图如下首先遍历fastbin和small bin,希望从中分到chunk。如果没有找到堆块,接下来就开始合并到fastbin中的堆块,合并完添加到unsorted bin中,然后进入到大循环。进入到大循环的路径有两个:1、请求堆块为large chunk。2、small bin中对应的bin为空1、将unsorted bin里面所有的chunk都添加到small bin和large bin里面去。走到大循环这一步,
2022-03-11 09:30:42
1073
原创 堆内存(1) - ptmalloc2分配器
ptmalloc2分配器ptmalloc2 分配给用户的内存都以 chunk 来表示,可以理解为 chunk 为分配释放内存的载体。下面根据glibc2.31对ptmalloc进行了分析。malloc_chunkmalloc_chunk用于管理内存块,该结构体维护了一张已使用和未使用内存块的链表struct malloc_chunk { INTERNAL_SIZE_T mchunk_prev_size; /* Size of previous chunk, if it is fre
2022-03-11 09:29:14
823
原创 Unix系统编程安装 tlpi_hdr.h头文件
安装tlpi_hdr.h头文件第一步:下载本书所给的源码文件并安装依赖wget “http://man7.org/tlpi/code/download/tlpi-161214-dist.tar.gz”sudo apt install libcap-dev libacl1-dev libselinux1-dev或者sudo yum install libcap-devel libacl-devel libselinux-devel第二步:解压后,make编译tar -zxvf tlpi-
2022-02-10 15:21:09
622
原创 SQLITE测试工具
sqlite数据库压测程序 SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库不一样,您不需要在系统中配置。就像其他数据库,SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接。SQLite 直接访问其存储文件。 首先得安装sqlite3和它的头文件固件环境 CPU:Intel® Core™ i7-1065G7 CPU @ 1.30GHz 内存: 16G 内核:lin
2021-12-20 17:44:36
9940
2
原创 linux下的进程结构
Linux进程表示 在Linux中使用task_struct表示一个进程描述符,该结构体包含了一个进程的所有信息// tags/v4.18 - include/linux/sched.hstruct task_struct {#ifdef CONFIG_THREAD_INFO_IN_TASK /* * For reasons of header soup (see current_thread_info()), this * must be the first element of t
2021-11-16 15:33:34
1130
1
原创 LInux ext4文件系统
Ext文件系统文件系统结构Boot Sector启动扇区,安装开机管理程序。Block Group:块组,存储数据的实际位置。也称为Boot Block。它位于分区上的第一个块,占用1024字节,并非所有分区都有这个boot sector,只有装了操作系统的主分区和装了操作系统的逻辑分区才有。里面存放的也是boot loader,这段boot loader称为VBR(主分区装操作系统时)或EBR(扩展分区装操作系统时),这里的Boot loader和mbr上的boot loader是存在交错关系的
2021-11-08 09:22:27
562
原创 文件流和文件描述符(使用unlink创建临时文件)
文件流和文件描述符 每个文件流都和一个底层文件描述符相关联,虽然可以通过底层的输入输出操作和文件流操作混合使用,但这样会导致难以预料的缓冲后果。unlink、link和symlink系统调用 如果一个文件的连接数减少的0,并且没有进程打开,这个文件就会被删除。事实上,目录项总是立刻被删除的,但文件所占用的空间要等到最后一个进程关闭才会被回收,rm程序使用的就是这个调用。先用open创建一个文件然后对其调用unlink是用来创建临时文件的技巧,这些文件只有在被打开的时候才能被调用,程序退出就会被
2021-07-04 21:27:28
262
原创 格式化输入输出(一)printf、scanf系列
printf、fprintf、sprintf函数 printf系列函数能够对各种不同类型的参数进行格式编派和输出,每个参数在输出流中的表示形式由格式参数format控制,它是一个包含需要输出的普通字符和称为转换控制字符的字符串,转换控制符规定了其余的参数应该以何种方式被输出到何种地方。#include"stdio.h"int printf(const char *format);int sprintf(char *s,const char *format );int fprintf(FILE
2021-07-04 21:03:45
135
原创 标准I/O库(fopen、Fread、fwrite、fclose、fflunsh)
标准I/O库 标准I/O库(stdio)及其头文件stdio.h为系统调用提供了一个通用的接口,这个库是ANSI标准C的一部分,在很多方面使用标准I/O库和使用描述符一样,首先需要打开一个文件以建立一个访问路径,这个操作的返回值将作为其他I/O库函数的参数。在I/O库中,与描述符对应的是流,以FILE类型的指针实现。fopen函数#include”stdio.h”FILE * fopen (const char *filename,const char *mode); fopen打开由f
2021-07-04 17:44:01
537
原创 底层系统调用(三)(mmap、msync、nummap、error))
mmap函数 mmap(内存映射)函数的作用是建立一段可以被两个或更多个程序读写的内存,一个程序对它做的修改可以被其他程序看到。这一功能可以用在文件处理上,方法,mmap函数创建一个指向内存区域的指针,该内存可以通过一个打开的文件描述符访问与文件的内容相关联。#include"stdio.h"void *mmap(void *addr,size_t len,int prot ,int flags,int fildes,off_t off); 可以通过传递参数off改变共享内存段访问的文件
2021-07-04 17:41:57
1218
原创 底层系统调用(open、write、read、close)
底层系统调用open系统调用 open可以创建一个新的描述符,成功返回文件描述符,失败返回-1,通常open系统调用不需要头文件sys/stat.h和sys/types.h但在某些UNIX系统上,它们必不可少,如果两个程序同时打开一个文件,它们会分别得到两个不同的文件描述符。如果它们都对文件进行写操作,那么它们会各写各的,分别接着上次离开的位置继续往下写。数据不会交织,而是彼此覆盖。两个程序对文件读写位置(偏移值)不同。可以通过使用文件锁防止这种现象出现。 O_RDONLY 只
2021-07-03 19:26:52
886
原创 Ftrace学习笔记与实践
ftrace详解 ftrace是一款内核自带的调试工具在2.6内核上就有了,可以用来辅助定位内核问题。详情可以看ftrace的官方文件。目前ftrace支持的类型有:function:函数调用跟踪追踪所有内核函数function_graph:函数图跟踪在函数的入口和退出上的迹线。 然后,它提供了绘制类似于C代码源的函数调用图的能力。blk:块追踪hwlat:硬件延迟示踪器用于检测硬件是否会产生任何延迟。 请参见下面的“硬件延迟检测器”部分。irqsoff:跟踪不可中断区域,记录最大延迟,
2021-06-23 10:08:17
1800
原创 挂接命令(mount)
挂接命令(mount)首先,介绍一下挂接(mount)命令的使用方法,mount命令参数非常多,这里主要讲一下今天我们要用到的。命令格式:mount [-t vfstype] [-o options] device dir其中:1.-t vfstype 指定文件系统的类型,通常不必指定。mount 会自动选择正确的类型。常用类型有:光盘或光盘镜像:iso9660DOS fat16文件系统:msdosWindows 9x fat32文件系统:vfatWindows NT ntfs文件系统:n
2021-06-22 09:00:47
658
原创 LInux 开机启动之MBR引导
Linux启动流程详解 操作系统的启动分为两个阶段引导(boot)和启动(startup),引导阶段开始于打开电源开关,结束于内核初始化完成和systemd进程。启动阶段接管了剩余的工作,直到操作系统进入可操作状态。 操作系统的开机引导和启动过程很容易理解,主要分为以下几个部分:BIOS上电自检(POST)引导装载程序(GRUB2)内核初始化启动systemd,其是所有进程之父上电自检 上电自检的过程其实Linux什么也没做,上电主要由硬件部分来完成,这对于所有的操作系统都一
2021-06-16 23:54:44
1537
2
原创 一个Linux目录扫描程序
扫描目录和扫描文件一样,目录其实也是一个文件,首先用opendir打开需要执行的目录它的形参是目录名,opendir会返回一个指向目录a的DIR类型的指针该结构体指针内包含了目录级别、文件描述符等可用来访问目录的信息。将该指针作为readdir函数的形参可以访问目录的索引信息。通过dirent中的文件名和路径可以使用lstat访问链接信息Created with Raphaël 2.2.0打开一个目录a,返回指向目录a的DIR结构体dp读取目录a下所欲文件,返回dirent结构体entry遍历结构体
2021-05-24 09:58:33
322
原创 Linux内核文件系统的底层调用
底层系统调用open系统调用 open可以创建一个新的描述符,成功返回文件描述符,失败返回-1,通常open系统调用不需要头文件sys/stat.h和sys/types.h但在某些UNIX系统上,它们必不可少,如果两个程序同时打开一个文件,它们会分别得到两个不同的文件描述符。如果它们都对文件进行写操作,那么它们会各写各的,分别接着上次离开的位置继续往下写。数据不会交织,而是彼此覆盖。两个程序对文件读写位置(偏移值)不同。可以通过使用文件锁防止这种现象出现。 O_APPEND:把写入数据追加在文
2021-05-19 17:58:15
243
原创 猜数游戏
猜数游戏 在生成随机数的时候如果我们没有设置随机数种子srand,系统会自动将随机数种子设为1,那么每次打开程序生成的随机数总会是同一序列的(如下图),要解决这个问题就需要我们设置随机数种子。以系统时间作为随机数种子进行随机猜数游戏//猜数字游戏输入多少次#include"stdio.h"#include"stdlib.h"#include"time.h"#define MAX_STAGE 10 //最多可以输入的次数int main(){ int i;//已经输入的次数
2021-05-19 13:22:24
120
原创 无符号编码和补码编码的区别
原码反码补码**原码:**一个数的原码(原始的二进制码)有如下特点:最高位做为符号位,0表示正,为1表示负其它数值部分就是数值本身绝对值的二进制数负数的原码是在其绝对值的基础上,最高位变为1**反码:**对于正数,反码与原码相同;对于负数,符号位不变,其它部分取反(1变0,0变1)注:反码运算也不方便,通常用来作为求补码的中间过渡。补码:在计算机系统中,数值一律用补码来存储。补码特点:对于正数,原码、反码、补码相同对于负数,其补码为它的反码加1符号位不动,源码其他位求反,最后整
2021-05-14 13:47:22
712
原创 C指针数组和数组指针
#指针数组和数组指针要弄清指针数组和数组指针的差别我们首先要弄清a与&a的区别, "&a"代表数组的起始地址a则代表首元素首地址 .int main(){ char a[5]={'A','B','C','D'}; char (*p1)[5] = &a; char (*p2)[5] = a; return 0;} 对于上述代码中p1、p2都是指向一个由5个字符变量组成的数组,&a是整个数组的起始地址,a是数组首元素的首地址,虽然他们两的值
2021-05-13 16:00:21
218
转载 详解C语言指针
前言:复杂类型说明要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其优先级和运算优先级一样,所以我总结了一下其原则:从变量名处起,根据运算符优先级结合,一步一步分析.下面让我们先从简单的类型开始慢慢分析吧:int p; //这是一个普通的整型变量int p; //首先从P 处开始,先与结合,所以说明P 是一个指针,然后再与int 结合,说明指针所指向的内容的类型为int
2021-05-13 13:39:08
169
转载 常用汇编指令
这里写目录标题常用汇编指令简单传送指令简单加减指令标志寄存器及其使用状态标准状态标志操作指令带进位加减指令取有效指针寄存器和简单控制转移指令常用条件转移指令堆栈操作过程调用和返回指令循环指令算数逻辑运算指令符号拓展指令拓展传送指令逻辑运算指令常用汇编指令简单传送指令指令名称格式解释备注MOV传送指令MOV DEST,SRCDEST<=SRCXCHG交换指令XCHG OPER1,OPER2把操作数oper1的内容与操作数oper2的内容交换oper
2021-05-11 10:09:26
596
原创 C语言运算符介绍
运算符“按位与”运算符(&)参加运算的两个数据,按二进制位进行“与”运算。如果两个相应的二进制位都为1,则该位的结果值为1;否则为0。例如 3&5=1 00000011(2)&00000101(2)=00000001(2)按位与的用途:(1)清零 若想对一个存储单元清零,即使其全部二进制位为0,只要找一个二进制数,其中各个位符合一下条件:原来的数中为1的位,新数中相应位为0。
2021-05-10 16:46:32
344
原创 外设I/O通信方式
外设通信方式 第一种,CPU通过I/O桥将键盘输入信息读入内部寄存器,然后将信息转到内存中 第二种,直接利用存储器存取(DMA)缓存技术 由于不同的存储技术在存储速度和造价上相差巨大,为了高效的访问数据,现代计算机的存储系统会把最常用的数据放在读存速度快的存储设备上,而把不常用的数据放在读存速度慢的存储设备上。存储器系统是一个具有不同容量、成本和访问时间的存储设备的层级结构。从上往下容量越来越大,但访问速度越来越慢。上一层做为下一层的缓存来存储访问频率更高的数据,比如,cpu寄存器保
2021-05-10 16:36:19
594
原创 ubuntu PicGo安装和腾讯云图床配置,超详细!!!
ubuntu下使用PicGo上传图片使用Typora编辑markdown文档可以让我们快速发布博客到不同的平台上,但当我们需要插入图片的时候如果使用的是绝对地址,我们会无法查看图片,但如果采用相对地址的解决方案,则必然需要把图片文件夹和.md放在一起,一点也不清爽。于是,将图片插入Typora时,将图片上传云端可以很好的解决这个问题。为了方便以后查阅和方便大家,将过程记录下来系统:ubuntu 18.04先安装Typora安装PicGo下载PicGo:GitHub在Linux系统选择Ap
2021-05-08 17:00:27
2657
2
基于内核秘钥保留服务的ELF文件签名程序和验签模块,编译好的内核中已经将kernel_key.pem秘钥环打入内核
2022-03-21
Sqlite性能测试程序
2021-12-20
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人