在当前目录下的所有文件中寻找某字符串: \{\} 表示fd找到的每个文件/路径,
将其传给 -exec 的子命令
fd . --type f # 文件类型 f, d ..
--exec grep --color=always -nH -e rust \{\} # -exec 对每个查找出来的文件路径执行命令
# 其中{}代表路径, \{\} 是为了防止歧义使用 -e 可以指定文件拓展名:
-e rs
-e cpp
-e c
fd . --type f -e c -e rs -e cpp -x grep --color=always -i -nH -e hello \{\}find -type f -exec grep --color=always -nH -e hello \{\} + # 对于find 的-exec子命令, {}后面需要接上加号+ !!grep --color=always -nH -i -e hello <FILE>
# -n 行号
# -H 文件名
# -e 正则表达式
# -i 忽略大小写
# --color=always 给查询结果上色
# --null 在文件名后面加上尾零.set +e 恢复默认:
set -eif [ -f $1 ]
then
else
fin* git
# 设置ss
git config --global http.proxy 'socks5://127.0.0.1:1080'
git config --global https.proxy 'socks5://127.0.0.1:1080'
# 设置代理
git config --global https.proxy http://127.0.0.1:1080
git config --global https.proxy https://127.0.0.1:1080
# 取消代理
git config --global --unset http.proxy
git config --global --unset https.proxygit submodule update --init --recursive
此命令经常无速度, 可能需要手动clone, 见 .gitmodules
git clone -b fsf-gdb-10.1-with-sim<分支> https://github.com/riscv-collab/riscv-binutils-gdb.git riscv-gdb<别名>
恢复容器的运行 :
sudo docker start `sudo docker ps -a -q`
sudo docker attach `sudo docker ps -aq`$ du -h linux-note.org
12K linux-note.orgdu -sh .* * | grep G
test `命令` = 'str'
test `命令` = 'string' -a `命令` = 'string'
test `命令` = "string" -o `命令` = 'string'E.g
# 判断当前平台是否是linux
test `uname -s` = 'Linux'
echo $? # 返回零表示无错误发生 pstree -ap | grep mysql/redis ...
在emacs中的shell运行pstree.
sun@Salted-PC:saltedf.github.io [main] $ pstree -ap | grep emacs
| `-emacs,65 -nw .
| | |-grep,217 --color=auto emacs
| `-{emacs},66
用于debug和理解程序的流程.
strace -f -s 65535 -i -t -T -p <pid> -o 输出文件 有时候会输出大量信息, 根本无法分析, 若只是需要特定的系统调用,可以使用
-e trace= 进行过滤, 如:负责读取/接收这类的系统调用.
-e trace=recvfrom,read,recv,recvmsg
strace -f -s 65535 -i -t -T -e trace=write,sendto,send -p <PID>
统计各个系统调用总耗时:
strace -c <程序>
strace -c -p <PID>结果显示了各个系统调用所花费总时间以及所占百分比, 调用次数, 以及出错次数. 出错越多一般代码质量越差.
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
49.27 0.009506 7 1281 clock_gettime
18.75 0.003617 9 390 rt_sigprocmask
9.05 0.001747 9 175 ioctl
8.12 0.001567 17 92 write
5.40 0.001042 23 45 pselect6
2.48 0.000478 28 17 fcntl
2.38 0.000459 13 35 rt_sigreturn
1.37 0.000265 6 38 read
1.37 0.000264 7 35 timerfd_settime
1.29 0.000249 27 9 poll
0.37 0.000071 35 2 kill
0.16 0.000030 15 2 getpid
0.00 0.000000 0 2 close
0.00 0.000000 0 2 openat
------ ----------- ----------- --------- --------- ----------------
100.00 0.019295 2125 total
代码分析组合拳: strace看关键调用. ==> 用calltree找出关键系统调用的调用关系. ==>用IDE细看这条调用链
objdump -D XXX | less 不加less会显示太多!
$ ldd ./build/udpclient
linux-vdso.so.1 (0x00007ffcb2d85000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f4c64e2a000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f4c64e0f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4c64c1d000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4c64ace000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4c65024000)code2html 的使用
先进入项目根目录:
- 代码转html
src2html.pl --tab-width 4 --color --cross-reference \
--navigator --line-numbers . <项目名>- html合成pdf
ebook-convert html_out/index.html llvm_release_1.pdf \
--use-profile-size \
--paper-size a3 \
--pdf-default-font-size 13 \
--pdf-mono-font-size 13 \
--margin-left 5 --margin-right 5 \
--margin-top 5 --margin-bottom 5 \
--page-breaks-before='/' https://github.com/lujun9972/linux-document/blob/master/examples/10%20wget%20command%20examples.org
wget --mirror --convert-links --page-requisites --no-parent -P /path/to/download https://example-domain.com
但这样可能会下载不全,原因可能有很多。这里遇到的问题是默认是不跨域名下载的。
需要运行第二次,并附加上多个选项
wget --mirror --convert-links -r -D "www.seas.upenn.edu,www.cis.upenn.edu" -A.pdf -A.zip -A.shtml --tries=1 --timeout=8 --span-hosts -l 5 --page-requisites --no-parent -P ./ https://www.seas.upenn.edu/\~cis341/17sp/
-
-A 指定那些没有被下载的文件类型 (需要观察网站特征获知)
-
–span-hosts 跨主机名下载。
-
-D 指定域名/主机名 list,否则将遍历大量无用的域名(需要观察网站特征获知)
-
–tries=1 重试一次,因为有些域名无法访问,也不含要下载的文件。
-
–timeout=10 设定超时时间,防止等待太长时间。
sudo vim /etc/apt/source.list
sudo apt-get updateyay -Sy dpkg
dpkg -i xxx.debcat ~/.Xresources修改后使配置生效:
xrdb ~/.Xresources
# or:
xrdb -merge ~/.Xresources 最后重启xterm.
! font and locale
xterm.locale: true
xterm.utf8: true
xterm*utf8Title: true
xterm*fontMenu*fontdefault*Label: Default
! 斜体在最后添加`:italic`
xterm*faceName: Sarasa Mono SC:antialias=true:style=Book
xterm*faceSize: 15
xterm*faceNameDoublesize: Sarasa Mono SC ! Noto Sans CJK SC
xterm*renderFont: true
xterm*xftAntialias: true
xterm*cjk_width: true
! 窗口设置
! 窗口大小及位置
xterm*geometry: 80x25
xterm*dynamicColors: true
xterm*saveLines: 2048
xterm*scrollKey: true
xterm*scrollTtyOutput: false
xterm*scrollBar: true
xterm*rightScrollBar: true
xterm*jumpScroll: true
xterm*multiScroll: true
xterm*toolBar: false
xterm*Scrollbar*thickness: 10
xterm*Scrollbar*background: black
xterm*Scrollbar*foreground: gray90
xterm*background: rgb:1a/1a/1a
xterm*foreground: rgb:d6/d6/d6
xterm*cursorColor: rgb:d6/d6/d6
! 提供xterm-256color类型支持
! 如果修改后,没有得到正确的结果,说明你可能需要安装ncurses-term包来提供xterm-256color类型支持
xterm*termName: xterm-256color
! 启用 Sixel 图形支持
xterm*decTerminalID: vt340
! 配置选择文本自动复制到剪贴板
! https://askubuntu.com/questions/237942/how-does-copy-paste-work-with-xterm
xterm*selectToClipboard: true
! 启用“Ctrl+v”来复制
xterm*VT100.Translations: #override \
<Btn1Up>: select-end(CLIPBOARD,PRIMARY,CUT_BUFFER0) \n\
Ctrl <KeyPress> V: insert-selection(CLIPBOARD,PRIMARY,CUT_BUFFER0)
! 解决Alt键不好使
xterm*eightBitInput: false
xterm*altSendsEscape: true
! 配置主题
! -- Tango color scheme
xterm*color0: #2e3436
xterm*color1: #cc0000
xterm*color2: #4e9a06
xterm*color3: #c4a000
xterm*color4: #3465a4
xterm*color5: #75507b
xterm*color6: #0b939b
xterm*color7: #d3d7cf
xterm*color8: #555753
xterm*color9: #ef2929
xterm*color10: #8ae234
xterm*color11: #fce94f
xterm*color12: #729fcf
xterm*color13: #ad7fa8
xterm*color14: #00f5e9
xterm*color15: #eeeeec
sudo service ssh restartsudo lsof -i :22 chown -R sun:sun ./dir.text: 代码段
.data: 常量 字符串 初始化的全局变量
.bss: 不占用实际空间, 仅仅标记那些局部变量和未初始化的全局变量.
因为已知初值的且生命周期长的变量才有提前为它们分配空间的必要,因此data段才占用空间. bss段中记录的是局部变量/未初始化的全局变量, 没必要一开始就为这些量准备好空间, 只要在程序实际运行时为其准备空间即可.
CC := gcc # 定义常量, 后续不能用+=
OBJS = hello.o world.o # 定义变量, 后续可以用+=增加
ObJS += fuck.o 通常是指那些不生成文件的. 只负责执行某些命令的.
.PHONY: clean # 这个之后的target都是伪目标
clean:
-${RM} *.o ${target}
echo "finish"
DEFS = -D_DEBUG -D_POSIX_SOURCE
FLAGS = -g ${DEFS}
LIBS = -lpthread -lqt
* 所有
% :任意一个文件
? :$@ 目标
$^ 全部的依赖文件
$< 首个依赖项 ${target} : ${OBJS}
${CC} ${FLAGS} -o $@ $^ ${LIBS}
%.o : %.c
${CC} -o $@ $^ $(my_func arg1,arg2,arg3)SRC = $(wildcard *.c) ==> hello.c world.c fuck.c OBJS = $(patsubset %.c,%.o,${SRC} )
# 将 SRC = hello.c fuck.c 替换成 hello.o fuck.o gef/cgdb/emacs gdb-many-windows
set environment FOO = XX unset environment FOO
- 进入gdb shell后:
run arg1 arg2 ...
set args arg1 arg2 arg3
- 启动gdb时通过命令行传参:
gdb ./main --args ./main a1 a2 a3 ...
这种方式需要额外再写一次可执行文件的路径.
l / list <函数> 默认显示10行
当有多个文件时, 为了显示其中一个文件要在文件名后加 :N ,
否则会被视作函数名.
list myfile.cc:1
用break可以添加断点, 既能在指定行上添加, 也能为指定函数添加断点.(经常用在一行中有多个函数时)
break myfile.cc:100
=====================
break myfunc显示了断点是否被禁用, 以及断点打在何处. 每个断点都有一个ID, 对断点的操作都基于此ID
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000408d60 in test_scanner_hello_Test::TestBody() at /home/sun/src/my_compiler/mytest/test_scanner.cc:10
(gdb) disable breakpoints 4
(gdb) i b
Num Type Disp Enb Address What
4 breakpoint keep n 0x0000000000408d60 in test_scanner_hello_Test::TestBody() at /home/sun/src/my_compiler/mytest/test_scanner.cc:10
(gdb) enable 4
(gdb) i b
Num Type Disp Enb Address What
4 breakpoint keep y 0x0000000000408d60 in test_scanner_hello_Test::TestBody() at /home/sun/src/my_compiler/mytest/test_scanner.cc:10
用断点序号指定要删除的断点
(gdb) delete breakpoints 1这个功能本身很简陋, 使用前提是源代码不能修改过. save breakpoints myfile
恢复断点: source <myfile>
不会进入函数内部.
continue
until <N行> 运行下面N行, 忽略之间的断点.
step
finish
return 相当于一种特殊的jump, 并不会将函数体执行完.并指定一个返回值
jump linenum
跳转后不会自动暂停, 需要断点.
info loacls
(gdb) print tk.kind_
$2 = mycompiler::Token::INTdisplay 每次都将这些变量的值打印处理.
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
1: y tk.kind_
undisplay + N
用what/whatis
(gdb) what tk.kind_
type = mycompiler::Token::Kind
(gdb) what 1+3
type = int
(gdb) whatis tk.kind_
type = mycompiler::Token::Kind可以在不修改源码的情况下对一些值进行设置.
(gdb) set var tk.kind_ = mycompiler::Token::END
只要这个值发生改变就会自动暂停,并显示新值和旧值.
watch tk.kind_
显示所有watchpoints info watchpoints
up/down: 上一层栈帧/下一层栈帧
frame N / f N 切换到指定栈帧中
首先需要获得其进程pid
attach PID
detach
通过fork出新的进程来保存当前运行位置和状态.
checkpoint
info checkpoints
delete checkpoint N
info threads
thread N
x/格式+长度 <地址>
记录反向运行所需信息
target record-full
reverse-next reverse-XXX
- 首先尝试更新系统到最新, 然后重启
sudo pacman -Syu
sudo reboot
- 否则可以试下安装
glibc-debug
在 /etc/pacman.conf 中临时启用:
[system-debug]
Server = https://debuginfod.artixlinux.org/$repo/os/$arch
[world-debug]
Server = https://debuginfod.artixlinux.org/$repo/os/$arch
[galaxy-debug]
Server = https://debuginfod.artixlinux.org/$repo/os/$arch
[lib32-debug]
Server = https://debuginfod.artixlinux.org/$repo/os/$arch
https://www.reddit.com/r/artixlinux/comments/wpji7m/valgrind_cant_load_debug_info/
sudo pacman -Sy glibc-debug
cmake_minimum_required(VERSION 3.21)
project(word-count C)
# 设置编译器
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_COMPILER clang)
add_compile_options(
"-ggdb" # gdb调试支持
"-m64"
)
# add_compile_definitions(LINE_COUNT) # 宏定义
## add_compile_definitions(MACRO_CONSTANT_NAME=macro_value)
# 生成 compile_commands.json 文件 for clangd
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include_directories(./include) # 头文件目录
add_executable(test_strcmp.bin)
target_sources(test_strcmp.bin PRIVATE
./test_strcmp.c
./str_cmp.c
)
# target_compile_options(test_strcmp.bin PRIVATE -ggdb)
# target_include_directories(YourExecutableName PRIVATE include)
add_executable(tokenize.bin)
target_sources(tokenize.bin PRIVATE
./tokenize.c
./vector_char.c
)
add_executable(dictionary.bin)
target_sources(dictionary.bin PRIVATE
./dictionary.c
./vector_char.c
./vector_string.c
./str_cmp.c
)
# add_executable(wordcount.bin)
# target_sources(wordcount.bin PRIVATE
# ./wordcount.c
# ./vector_char.c
# ./table_string.c
# ./str_cmp.c
# )
add_executable(linecount.bin)
target_sources(linecount.bin PRIVATE
./linecount.c
./vector_char.c
./table_string.c
./str_cmp.c
)
add_executable(duplicate.bin)
target_sources(duplicate.bin PRIVATE
./dedup.c
./vector_char.c
./table_string.c
./duplicate.c
./str_cmp.c
)
add_executable(unit_test_vector_char.bin)
target_sources(unit_test_vector_char.bin PRIVATE
./unit_test_vector_char.c
./vector_char.c
)
# add_executable(unit_test_vector_string.bin)
# target_sources(unit_test_vector_string.bin PRIVATE
# ./unit_test_vector_string.c
# ./vector_string.c
# ./str_cmp.c
# )
add_executable(unit_test_table_string.bin)
target_sources(unit_test_table_string.bin PRIVATE
./unit_test_table_string.c
./table_string.c
./vector_char.c
./str_cmp.c
)
在项目根目录下添加文件: .clangd 参考:
https://clangd.llvm.org/config#compileflags
CompileFlags:
Add: [-xc,-std=c99]
Compiler: clang
CompileFlags: # Tweak the parse settings
Add: [-xc++, -std=c++20] # treat all files as C++
Compiler: clang++ # Change argv[0] of compile flags to `clang++`
查看cgroup 版本:
cat /proc/mounts | grep cgroupcgroup2(伪)文件系统位于:
/sys/fs/cgroup其文件系统类型是 cgroup2 其接口是通过文件系统来提供的.
control groups 由两个部分组成:
- 一组进程
- 控制器(subsystem), 对进程组进行控制.
control group: 一组进程出于资源管理的目的被绑在一起.这组进程共享同一个内存分配或者cpu
-
限制组的资源使用 限制某个组的cpu可用百分比/ 可用内存的百分比
-
调整组的资源分配优先级 例如网络带宽
-
测量资源使用情况
-
冻结一个组 通过不给这个组CPU时间, 并且在之后可以恢复他们.
mkdir/rmdir 创建cgroups
每个子目录包含了被自动创建出的文件.一些文件是用来管理cgroup自身的.(eg哪些进程属于这个cgroup) 另一些是和特定的控制器相关的.
sudo bash
cd /sys/fs/cgroupcat cgroup.controllers
cpuset cpu io memory hugetlb pids rdma misccat cgroup.subtree_control
cpuset cpu io memory pids创建一个cgroup
mkdir mygrp将当前shell进程移入这个组:
echo $$ > mygrp/cgroup.procscat cgroup.procs
106480
106851一个pid是bash, 另一个是bash的子进程 cat. fork创建出的子进程自动和父进程同属一个cgroup.
查看当前进程所在的cgroup信息:
cat /proc/$$/cgroup
0::/mygrp查看当前cgroup中有几个进程:
cat mygrp/pids.current
2查看最大容许的进程数量
cat mygrp/pids.max
max # 代表没有限制echo 5 > mygrp/pids.max
echo 4 > mygrp/pids.max
cat mygrp/pids.max
4然后通过这个shell创建多个sleep进程, 可以观察到无法创建出更多进程了.
for j in $(seq 1 5); do sleep 60 & done
[1] 109424
[2] 109425
[3] 109426
bash: fork: retry: Resource temporarily unavailable
bash: fork: retry: Resource temporarily unavailable
bash: fork: retry: Resource temporarily unavailable
bash: fork: retry: Resource temporarily unavailable
bash: fork: Resource temporarily unavailable无法直接rmdir非空的(有进程)cgroup.
先将shell进程移动到父cgroup中
echo $$ > /sys/fs/cgroup/cgroup.procs 然后查看mygrp中的进程个数:
cat /sys/fs/cgroup/mygrp/pids.current
0为零, 可见顺利将shell移出了mygrp.
此时可以用rmdir成功删除之前创建的cgroup. (那些被内核自动创建出来的文件无需删除,也无法被删除)
限制并测量cpu的使用. 有两种模式, 可以混合使用:
- 比例权重(默认)
- 带宽控制模式
权重模式只在发生cpu争用时才会施加限制:
带宽模式即使在没有其它组的进程时也会严格施加限制:

