跳转至

2023

GDB

GDB 基本命令

  • -next单步执行
  • -step单步进入
  • finish 跳出当前函数
  • 跳出当前函数 finish: Continue running until just after function in the selected stack frame returns. Print the returned value (if any). This command can be abbreviated as fin.
  • -continue继续执行到下一个断点
  • -until继续运行到指定位置

运行带参数程序

  • gdb --args 正常程序+参数
  • 进入gdb后运行 set args 参数

break断点

  • f 打印当前文件 ,便于打断点
  • info breakpoints 查看已经的断点
  • del 3 删除NUM=3的第三个断点
给某个结构体内的函数全部上break
rbreak file.cpp:.*TemplateClass.*

GDB 打印信息

  • 参数 show args
  • 局部变量 info locals
  • 修改变量 p result=20
  • 函数调用栈 bt

打印结构体class

gef➤  p -raw-values off -- this->TotalCycles
gef➤  p this                                                                                                                                                                                                                         
$11 = (llvm::mca::SummaryView * const) 0x7fffffffcc08                                                                                                                                                                                
gef➤  p *this

打印指针变量

  • 二维指针 p **matrix@3@3
  • 一维指针 p *matrix@3
  • 或者转换为数组 p *(int *)matrix@3
  • 或者转换为数组 p *(int (*)[3])matrix

打印数组

(gdb) p array[60]@10
$9 = {60, 61, 62, 63, 64, 65, 66, 67, 68, 69}

可以看到打印了array数组第60~69个元素的值。如果要打印从数组开头连续元素的值,也可使用这个命令:“p *array@num”:

(gdb) p *array@10
$2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

GDB中查看指定内存地址内容的指令

examine命令(简写是x)

格式:x /nfu <addr> 说明:

  • x是examine的缩写
  • n表示要显示的内存单元的个数
  • f表示显示方式,可取如下值
  • x按十六进制格式显示变量。
  • d按十进制格式显示变量。
  • u按十进制格式显示无符号整型。
  • o按八进制格式显示变量。
  • t按二进制格式显示变量。
  • a按十六进制格式显示变量。
  • i指令地址格式
  • c按字符格式显示变量。
  • f按浮点数格式显示变量。
  • u表示一个地址单元的长度
  • b表示单字节,
  • h表示双字节,
  • w表示四字节,
  • g表示八字节

example:

(gdb) x 0x8049948
0x8049948: 0x20726f46
(gdb) x/s 0x8049948
0x8049948: "For NASA,space is still a high priority."
(gdb) x/4 0x7fffe536dbc0 # display 4 bytes info?
0x7fffe536dbc0: 0x0     0x0     0x9d835 0x0

打印寄存器值(表格)

layout split
layout regs
tui reg general

gef 界面

效果

真好用,什么都会打印

安装gef

bash -c "$(curl -fsSL http://gef.blah.cat/sh)"

# 没有网,手动下 https://gef.blah.cat/py ,替换
$ wget -O ~/.gdbinit-gef.py -q https://gef.blah.cat/py
$ echo source ~/.gdbinit-gef.py >> ~/.gdbinit

注意:gdbtui 与 gef 不太兼容

需要进一步的研究学习

之前gdbtui的使用写在notion上了

https://shaojiemike.notion.site/GDB-d53a1be0b6324234a2ae43b7c27a23b8## 遇到的问题 暂无

开题缘由、总结、反思、吐槽~~

参考文献

Linux Network Command Guide

lsof

  • lsof(list open files)是一个列出当前系统打开文件的命令。
  • 由于在linux环境下,任何事物都以文件的形式存在
  • 所以通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件

输出格式

$lsof -i
COMMAND       PID        USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
node        82138 shaojiemike   20u  IPv4 101994394      0t0  TCP localhost:34075->localhost:56220 (ESTABLISHED)
hugo      4042646 shaojiemike    9u  IPv4  99496788      0t0  TCP localhost:xtel (LISTEN)
ssh       4080263 shaojiemike    3u  IPv4 100792902      0t0  TCP snode6:40592->ec2-54-82-85-249.compute-1.amazonaws.com:ssh (ESTABLISHED)

$lsof
init          1        root  rtd       DIR                8,1     4096          2 /
init          1        root  txt       REG                8,1   150584     654127 /sbin/init

值得解释的参数:

  • COMMAND:进程的名称
  • FD:文件描述符,应用程序通过文件描述符识别该文件。
  • cwd 值表示应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改。
  • txt 类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序。
  • 数值表示应用程序的文件描述符,这是打开该文件时返回的一个整数。
    • 由于初始打开每个应用程序时,都具有三个文件描述符,从 0 到 2,分别表示标准输入、输出和错误流。所以大多数应用程序所打开的文件的 FD 都是从 3 开始。
  • u 表示该文件被打开并处于读取/写入模式,而不是只读 r 或只写 (w) 模式。
    • 大写的W 表示该应用程序具有对整个文件的写锁。该文件描述符用于确保每次只能打开一个应用程序实例。
  • mem memory-mapped file;
  • rtd root directory;
  • TYPE:文件类型
  • REG 和 DIR分别表示文件和目录。
  • CHR 和 BLK,分别表示字符和块设备;
  • UNIX、FIFO 和 IPv4,分别表示 UNIX 域套接字、先进先出 (FIFO) 队列和网际协议 (IP) 套接字。
  • DEVICE:指定磁盘的名称
  • SIZE:文件的大小
  • NODE:索引节点(文件在磁盘上的标识)
  • NAME:打开文件的确切名称

常见用法

  • 打开文件的进程lsof abc.txt
  • 进程打开的文件
  • 根据进程名lsof -c abc
  • 根据PIDlsof -c -p 1234
  • 当前目录下被打开的文件lsof +d /usr/local/
  • 允许向下递归目录lsof +d /usr/local/
  • 筛选和网络相关的lsof -i默认打印所有网络相关的
lsof -i[46] [protocol][@hostname|hostaddr][:service|port]
  46 --> IPv4 or IPv6
  protocol --> TCP or UDP
  hostname --> Internet host name
  hostaddr --> IPv4地址
  service --> /etc/service中的 service name (可以不止一个)
  port --> 端口号 (可以不止一个)

常见用例

lsof -i UDP@[url]www.akadia.com:123 //显示那些进程打开了到www.akadia.com的UDP的123(ntp)端口的链接
lsof -i [email protected]:ftp -r //不断查看目前ftp连接的情况(-r,lsof会永远不断的执行,直到收到中断信号,+r,lsof会一直执行,直到没有档案被显示,缺省是15s刷新)

特殊端口替代符号

lsof -i :8080会用特殊的端口替换名称代替,常见的见文档

> sudo lsof -i  :8080
COMMAND      PID    USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
qbittorre 102376 chivier    9u  IPv6 257158435      0t0  TCP *:http-alt (LISTEN)

常见端口号 | 替换名称 | ---|---| |21|ftp| |22|ssh| |80|http| |8080|http-alt| |8090|http_alt_alt| |443|https

htop命令

  • 按键h?或者F1进说明界面,介绍快捷键hotkey
    • 注意大小写, 前面亮蓝色的F9 k代表F9k两按键都可以实现功能
    • u 可以指定用户的进程
    • H 显示或隐藏user线程
    • K 显示或隐藏kernel线程。 值得注意显示的PID,其实是PID或者TID(thread id)
    • e 可以打印环境变量
  • F5可以在两模式间切换
    • sort模式时,F6为SortBy可以选择排序方式
    • Tree模式时,F6为Collapse折叠子进程

常规设置以及解释

  • F2中布局设置如下(注意分成左右两大块)
    • "load average",它的意思是"系统的平均负荷",里面有三个数字,意思分别是1分钟、5分钟、15分钟内系统的平均负荷。当CPU完全空闲的时候,平均负荷为0;当CPU工作量饱和的时候,平均负荷为1。
    • 如果CPU每分钟最多处理100个进程,系统负荷1.7,意味着除了CPU正在处理的100个进程以外,还有70个进程正排队等着CPU处理。
    • 多核或者多CPU情况:n个CPU的电脑,可接受的系统负荷最大为n
  • F2中Dispaly options 除开隐藏用户态线程,其他建议全部勾选
  • F2中Columns设置每个进程显示的内容
  • 建议添加
    • STARTTIME
    • PPID 父进程PID
    • NLWP Number of threads in the process
  • 根据情况添加
    • 分析程序时间 user_time & system_time
    • 程序数据占用大小 M_LRS The library size of the process
    • IO读取的数据和速率 IO_RATE(需要sudo才能采集)

常用参数解释

START     PID    PPID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
  • PRIORITY
    • Kernel's internal priority for the process
  • NICE
    • Nice value (the higher the value,the more it lets other processes take priority)
    • 所以F7 Nice- 调高优先级,F8 Nice+ 降低优先级
  • PROCESSOR
    • Id of the CPU the process last executed on
  • M_SIZE
    • Total program size in virtual memory
    • 进程占用的虚拟内存值
  • M_RESIDENT
    • Resident set size,size of the text and data sections,plus stack usage
    • 进程占用的物理内存值
  • M_SHARE
    • Size of the process's shared pages
    • 进程占用的共享内存值
  • PERCENT_CPU
    • Percentage of the CPU time the process used in the last sampling (0~n)
  • PERCENT_MEM
    • Percentage of the memory the process is using, based on resident memory size
    • 该进程占用的物理内存和总内存的百分比
  • TIME
    • Total time the process has spent in user and system time
  • Status:
    • R: running;
    • S: sleeping;
    • T: traced/stopped;
    • Z: zombie;
    • D: disk sleep

常见用法

  • 先使用F4查找到进程名对应的PID,然后退出F4查找,直接输入pid可以知道其是否是僵尸进程

ip rule 与 ip route

传统路由

传统路由是基于目的地址来路由,如route命令。但是已经不再被使用。

$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         0.0.0.0         0.0.0.0         U     0      0        0 warp
default         202.38.73.254   0.0.0.0         UG    0      0        0 eno0
  • 显示所有的流量都走名为warp的wireguard虚拟网卡。如果第一条wg的路由规则,所有流量原本应该走网关202.38.73.254
  • 参数基本说明
  • Metric 路由距离,到达指定网络所需的中转数,是大型局域网和广域网设置所必需的 (Linux内核不再使用)
  • Ref 是路由项引用次数 (Linux内核不再使用)
  • 相关Flags含义:
    • U 路由是活动的
    • G 需要经过网关
    • ! 拒绝路由
    • n 表示该路由是一个主机路由(而不是网络路由)
$ route -6
Kernel IPv6 routing table
Destination                    Next Hop                   Flag Met Ref Use If
[::]/0                         [::]                       !n   -1  1     0 lo

[::]/0                         2001:da8:d800:730::1       UG   1024 65     0 eno0
ip6-localhost/128              [::]                       Un   0   57     0 lo

以上是ipv6的相关输出

ip ro命令 ip route 命令

ip ro命令是ip route命令的缩写,默认显示的是ip route show table main也就是main 路由表

注意每个路由表的内容,如果满足几个路由规则,路由的优先级是按照匹配前缀最长的路由。而不是按照第一行优先于第二行。

root@tsjOp ~  [03:02:19]
> ip ro
default via 114.214.235.254 dev eth1  src 114.214.233.141
10.0.233.2 dev wg1 scope link
10.0.233.3 dev wg1 scope link
10.0.233.4 dev wg1 scope link
10.0.233.5 dev wg1 scope link
10.0.233.6 dev wg1 scope link
10.0.233.7 dev wg1 scope link
114.214.232.0/22 dev eth1 scope link  src 114.214.233.141
192.168.31.0/24 dev br-lan scope link  src 192.168.31.1

对于目的地址为10.0.233.2的信包,虽然也匹配default规则,但是32位全匹配10.0.233.2 dev wg1 scope link,所以最终选择wg1.

ip rule指令

Usage: ip rule [ list | add | del ] SELECTOR ACTION (add 添加;del 删除; llist 列表)

SELECTOR := [ from PREFIX 数据包源地址] [ to PREFIX 数据包目的地址] [ tos TOS 服务类型]
            [ dev STRING 物理接口] [ pref NUMBER ] [fwmark MARK iptables 标签]

ACTION := [ table TABLE_ID 指定所使用的路由表] [ nat ADDRESS 网络地址转换]
          [ prohibit 丢弃该表| reject 拒绝该包| unreachable 丢弃该包]

[ flowid CLASSID ]

TABLE_ID := [ local | main | default | new | NUMBER ]

查看指定ip的路由

root@tsjOp ~  [01:46:08]
> ip route get 20.205.243.166
20.205.243.166 via 114.214.235.254 dev eth1  src 114.214.233.141
root@tsjOp ~  [01:48:07]
> ip route show to match 20.205.243.166
default via 114.214.235.254 dev eth1  src 114.214.233.141

iptables

Linux 网络管理机制

在命令的学习和实践中,逐步学习。Linux系统是如何管理网络的。

node5 problem

$ ip route show table default
Error: ipv4: FIB table does not exist.
Dump terminated

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

我想写关于 linux 网络命令 ip iptables ufw 的相关文档来全面表述linux网络的构成和如何控制管理

参考文献

https://www.cnblogs.com/ggjucheng/archive/2012/01/08/2316599.html

https://zhuanlan.zhihu.com/p/144585950

Wake Up Process

Linux 多进程的竞争休眠机制

基本是基于Linux的时间片轮转机制。A process/thread is woken up by inserting it in the queue of processes/threads to be scheduled.

内核调度算法

CFS(Completely Fair Scheduler)是一种用于 Linux 操作系统的调度算法,它旨在实现对 CPU 时间的公平分配。CFS 是 Linux 内核中默认的调度器,自 Linux 2.6.23 版本以来就成为了标准调度器。

CFS 调度算法的主要目标是确保各个任务在相同的时间片内能够获得公平的CPU时间,不会因为优先级等因素而造成资源争夺不均。以下是 CFS 调度算法的一些关键特点和原则:

  1. 虚拟化时钟: CFS 使用了一种称为虚拟化时钟(virtual runtime)的概念,而不是传统的时间片。每个任务都有一个虚拟运行时间,调度器根据虚拟运行时间来决定哪个任务应该被调度。

  2. 权重: CFS 引入了权重的概念,用于调整不同任务的相对优先级。较高权重的任务会在相同时间间隔内获得更多的虚拟运行时间,从而实现按比例分配CPU资源。

  3. 累积虚拟运行时间: 调度器会根据每个任务的权重和已累积的虚拟运行时间,计算出每个任务的应有的虚拟运行时间片。任务在使用完它的时间片后,会根据虚拟运行时间进行重新排队。

  4. 红黑树结构: CFS 使用红黑树来管理任务队列,这种数据结构使得在插入、删除和搜索任务时的时间复杂度保持在对数级别。

除了 CFS,Linux 内核还有其他调度算法,如:

  • 实时调度器(Real-Time Scheduler): 用于实时任务,提供硬实时和软实时的调度策略,确保实时任务在指定的时间内执行完成。

  • O(1) 调度器(O(1) Scheduler): 是 Linux 2.4 内核中使用的调度器,它的时间复杂度为常数级别。然而,随着多核系统的出现,O(1) 调度器在多核环境下的性能表现受到限制,因此被 CFS 替代。

这些调度算法在不同的场景和需求下,对于多任务操作系统的调度提供了不同的方法和策略。选择适合的调度算法可以根据系统的应用和性能要求来进行。

问题

在高强度竞争之后,有些进程陷入长期sleep,并且在核空闲的时候,也不再重新运行?为什么?

原因可能是程序逻辑阻塞了,或者在等待IO

查看进程Sleep的原因

首先 计算机对一个进程是如何判断sleep的,是某时间内的计算占比低于某个阈值吗?

htop s 可以查看kernel 是不是阻塞, l 可以查看是不是读写同一个文件导致阻塞了。

Sleep的瓶颈在哪里

sleep for what, waiting for what?

实践1 strace

strace -p PID 可以显示一些信息

$ strace -p 4005042
  wait4(-1, # 等待任意子进程结束

# check subprocess
$ pstree -p 4005042
pinbin(4005042)---BC_Compute(4005082)-+-{BC_Compute}(4005187)
                                      |-{BC_Compute}(4005188)
                                      |-{BC_Compute}(4005252)
                                      |-{BC_Compute}(4005296)
                                      |-{BC_Compute}(4005299)
                                      `-{BC_Compute}(4005302)

$ strace -p 4005082
strace: Process 4005082 attached
futex(0x7fffe52de1b8, FUTEX_WAIT, 2, NULL
# futex - fast user-space locking(seems to be used in OpenMP)
# It is typically used as a blocking construct in the context of shared-memory synchronization. 


$ strace -p 4005188
nanosleep({tv_sec=0, tv_nsec=2000000}, 0x7fffe5368bc0) = 0 # repeat
nanosleep({tv_sec=0, tv_nsec=2000000}, 0x7fffe536dbc0) = 0

It seems this is a subprocess repeating sleep leading to all other process to wait in the synchronization.

Use gdb -p PID to attach the process to locate the infinite loop (need Debug Symbols).

futex解释

futex 是 Linux 下的一个系统调用,用于实现用户空间线程间的同步和通信。让我们逐个解释这个系统调用中的每个参数的含义:

  1. 0x7fffe52de1b8: 这是一个指向内存地址的指针(或称为地址),通常是用于表示需要同步的资源或变量的地址。在这里,它表示需要等待的共享资源或变量的地址。
  2. FUTEX_WAIT: 这是一个指定 futex 要执行的操作的标志。FUTEX_WAIT 表示线程正在等待 futex 的值发生变化,即等待条件满足。当某个线程执行 FUTEX_WAIT 操作时,如果 futex 的值与预期不符,则该线程将被置于休眠状态,直到 futex 的值发生变化或超时。
  3. 2: 这是一个表示期望的 futex 值的参数。当调用 FUTEX_WAIT 时,线程将检查 futex 的当前值是否等于此参数指定的值。如果不等于,则线程将休眠等待。
  4. NULL: 这是一个指向 timespec 结构的指针,用于设置超时。这里为 NULL 表示调用没有设置超时,即线程将一直等待,直到 futex 的值发生变化。

总的来说,futex(0x7fffe52de1b8, FUTEX_WAIT, 2, NULL) 表示线程正在等待位于内存地址 0x7fffe52de1b8 的 futex 变量的值等于 2。如果 futex 的值不是 2,则线程将一直等待直到 futex 的值变为 2 或者超时。这样的同步机制在多线程编程中用于等待条件满足后再执行某些操作,从而避免资源竞争和提高程序的并发性能。

nanosleep解释

这是一个系统调用 nanosleep 的输出,通常用于让线程休眠一段时间。让我们逐个解释这个系统调用的含义:

nanosleep({tv_sec=0, tv_nsec=2000000}, 0x7fffe5368bc0) = 0
  1. nanosleep: 这是 Linux 下的一个系统调用,用于使线程休眠一段指定的时间。

  2. {tv_sec=0, tv_nsec=2000000}: 这是传递给 nanosleep 的第一个参数,是一个指向 timespec 结构的指针。timespec 结构用于表示时间间隔,包括秒(tv_sec)和纳秒(tv_nsec)。

在这里,tv_sec=0 表示秒数为 0,tv_nsec=2000000 表示纳秒数为 2000000。因此,这个 nanosleep 调用将会使线程休眠 2 毫秒(1 秒 = 1000000000 纳秒,所以 2000000 纳秒就是 2 毫秒)。

  1. 0x7fffe5368bc0: 这是传递给 nanosleep 的第二个参数,表示一个 timespec 结构的指针。这个参数用于存放未休眠完成的剩余时间,如果 nanosleep 被中断(例如收到信号),它将在这个指针中返回剩余的时间。在这个输出中,剩余时间被存储在内存地址 0x7fffe5368bc0 处。

  2. = 0: 这是 nanosleep 的返回值,表示成功完成。返回值为 0 表示 nanosleep 成功休眠了指定的时间。

综上所述,这个输出表示线程成功休眠了 2 毫秒。

实践2: zsim模拟程序

程序直接执行正常,zsim模拟直接sleep?

$ strace -p 303359
read(10,

$ pstree -p 303359                                                                                 gups_vanilla(303359)-+-gups_vanilla(303449)-+-orted+                                                                    |                      `-{gups+                                                                    |-{gups_vanilla}(303360)                                                                           |-{gups_vanilla}(303361)

$ pstree -p 303449                                                                                 gups_vanilla(303449)-+-orted(303451)-+-{orted}(303452)                                                                  |               |-{orted}(303642)                                                                  |               |-{orted}(303643)                                                                  |               `-{orted}(303644)                                                                  `-{gups_vanilla}(303450)

这是一个 Open MPI(Message Passing Interface)的启动命令,用于启动一个 MPI 程序,并配置一些运行时参数。让我们逐个解释这个命令中的每个选项和参数的含义:

orted --hnp --set-sid --report-uri 11 --singleton-died-pipe 12 -mca state_novm_select 1 -mca ess hnp -mca pmix ^s1,s2,cray,isolated

部分参数含义如下:

  • orted: 这是 Open MPI 的一个工具,用于启动和管理 MPI 进程。
  • -mca state_novm_select 1: 这是一个 MCA(Modular Component Architecture)选项,用于指定某个模块或组件的参数设置。在这里,state_novm_select 设置为 1,可能是指定某个组件或模块在运行时的选项。
  • -mca pmix ^s1,s2,cray,isolated: 这是另一个 MCA 选项,用于配置 PMIx(Process Management Interface for Exascale)的相关设置。^s1,s2,cray,isolated 表示排除 s1、s2、cray 和 isolated 这些模块,可能是禁用某些特定的组件或功能。
pid strace output explanation
303451 restart_syscall(<... resuming interrupted read ...>
303452 futex(0xabba001ec8, FUTEX_WAIT, 2, NULL
303642 epoll_wait(18, ... epoll_wait 系统调用,用于等待文件描述符18上的事件
303643 select(50, [48 49], NULL, NULL, 如下
303644 select(53, [51 52], NULL, NULL,
  • restart_syscall表示系统调用被中断后重新启动的过程。它通常出现在系统调用的执行过程中,当某个信号(例如 SIGSTOP 或 SIGCONT)中断了系统调用的执行,然后系统调用在信号处理完成后被重新启动。
  • select 是一个用于在多个文件描述符上进行 I/O 多路复用(I/O multiplexing)的系统调用,它可以监视多个文件描述符,并在其中任何一个文件描述符准备好进行 I/O 操作时返回。
  • select 调用的输出,它将监视文件描述符 48 和 49,并在其中任何一个文件描述符准备好读取数据或超时(2 秒后)时返回。
  • 完全无法理解呢! 可能需要深入了解MPI的实现栈细节才能明白。

命令行唤醒Sleep进程

The only way to “wake it up” is to arrange for the condition to be met. 用户是无法更改的状态的。

传统kill进程

# find pid , state S+ meaning sleep
ps aux | grep name
# gracefully kill process
kill -15 pid

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

上面回答部分来自ChatGPT-3.5,没有进行正确性的交叉校验。

PPT acadamic figure

🏗施工中🏗

🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧

觉得有意义写,先占个位子。还没写好呢,建议不要看(逻辑内容都没想清楚),不要急~~

🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧

核心思想

画图是为了解释文字难以说清的事情。

  1. 明确要说明的观点和内容。需要时完整但是不复杂的内容,复杂的内容会导致内容的丢失。
  2. 明确需要图形化的对象(除开)
  3. 明确对象的重要性,越重要-> 越大、颜色越鲜艳、字体越粗。(大小如果是写实的就保持实际)
  4. 对象间的关系(通常用小字说明): 顺序大小关系(箭头),集合关系(花括号,虚实方框包裹)
  5. 保持画面和谐
  6. 对象的空间分布均匀,大小均匀,有层次。主要对象居中且保持对齐。
  7. 颜色有限,重点突出
  8. 最终效果:读者知道按照什么顺序看图,图形的关键是什么,作者想说明什么。

其实这些都是自然的东西,好像也不需要总结。

常见类型

  1. 流程图(只是展示理清每个关键步骤,还是更具体到每个步骤的核心实现方法)
  2. 实例说明图(抽象概念往往难以理解,实例说明更容易理解)
  3. 复杂概念的关系图

注意事项

图形的选择、大小和位置

  1. 虚实方框包裹 表示 弱或强的同类型关系

字体的选择、大小、位置、字体和粗细斜体

颜色

  1. 基本配色(统一的重要性关系): 红 > 黄 > 蓝/绿 > 灰/黑
  2. 颜色赋予的含义:红最重要, 黑色一般时baseline

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

上面回答部分来自ChatGPT-3.5,没有进行正确性的交叉校验。

Overview of Compute system

“Those who cannot remember the past are condemned to repeat it.” —George Santayana, 1905
"Our technology,our machines,is part of our humanity.We created them to extend ourself,and that is what is unique about human beings. - Ray Kurzweil

Script: Email notifications when machine is free

outline

login to free SMTP server(qq, google) to send email to others.

send email using command line

  1. check ping mail.ustc.edu.cn
  2. MUST : set gmail open to support SMTP and apppassword
  3. or config qq email

IMAP, POP3 or SMTP

mailutils

According to ref1.

# install ca-certificates
# After new a google accounts, 
# config according to ref1
sudo apt-get install mailutils
$ echo "Hello world" | mail -s "Test" [email protected]

send but the same, more crazy thing is the -v and -d flag is not supported. and --debug-level=trace0 isn't recognized. many same question in StackOverflow

sudo tail -n 30 /var/log/mail.log or mail.error show more info.

ssmtp

We try ref2 ssmtp, sudo vim /etc/ssmtp/ssmtp.conf

TLS_CA_FILE=/etc/pki/tls/certs/ca-bundle.crt
root=[email protected]
mailhub=smtp.gmail.com:587
rewriteDomain=gmail.com
AuthUser=shaojieemail
AuthPass={apppassword}
FromLineOverride=YES
UseSTARTTLS=Yes
UseTLS=YES
hostname=snode6

The config get work but not well configed, e.g., TLS_CA_FILE

sending a email using gmail took about 13 mins.

$ ssmtp 943648187@qq.com < mail.txt
......
[->] Received: by snode6 (sSMTP sendmail emulation); Wed, 06 Sep 2023 15:42:05 +0800
[->] From: "Shaojie Tan" <[email protected]>
[->] Date: Wed, 06 Sep 2023 15:42:05 +0800
[->] test server email sending
[->]
[->] .
[<-] 250 2.0.0 OK  1693986323 5-20020a17090a1a4500b0026b4ca7f62csm11149314pjl.39 - gsmtp
[->] QUIT
[<-] 221 2.0.0 closing connection 5-20020a17090a1a4500b0026b4ca7f62csm11149314pjl.39 - gsmtp

sendmail

$ sendmail [email protected] < mail.txt
sendmail: Authorization failed (535 5.7.8  https://support.google.com/mail/?p=BadCredentials e7-20020a170902b78700b001c0c79b386esm8725297pls.95 - gsmtp)

get to work after well config gmail setting.

Speed Compare

command snode6 time(mins) icarus1
mail 4 1s
ssmtp 13
sendmail 6

send email by python

ref using QQ apppassword and python.

email notifications

  1. Create a Bash Script: Create a Bash script that checks the CPU usage and sends an email if it's below 30%. For example, create a file named cpu_check.sh:
#!/bin/bash

# Get CPU usage percentage
cpu_usage=$(top -b -n 1 | grep '%Cpu(s):' | awk '{print $2}' | cut -d'.' -f1)
echo "cpu_usage : ${cpu_usage} on $(hostname)"
# Check if CPU usage is below 30%
if [ "$cpu_usage" -lt 30 ]; then
   echo "beyond threshold : ${cpu_usage} on "
    # Send an email
    echo "CPU usage is ${cpu_usage} below 30% on $(hostname)" | mail -s "Low CPU Usage Alert on $(hostname)" [email protected]
fi

Make the script executable:

chmod +x cpu_check.sh

Modify [email protected] with your actual email address.

  1. Schedule the Script: Use the cron scheduler to run the script at regular intervals. Edit your crontab by running:
crontab -e

Add an entry to run the script, for example, every 5 minutes:

*/5 * * * * /staff/shaojiemike/test/cpu_check.sh >> /staff/shaojiemike/test/cpu_check.log
# Run every 15 minutes during working hours (9 am to 7 pm)
*/15 9-19 * * * /path/to/your/script.sh

Replace /path/to/cpu_check.sh with the actual path to your Bash script.

  1. Save and Exit: Save the crontab file and exit the text editor.

Now, the script will run every 5 minutes (adjust the cron schedule as needed) and send an email notification if the CPU usage is below 50%. You should receive an email when the condition is met.

Please note that this is a basic example, and you can modify the script to include more details or customize the notification further as needed. Additionally, ensure that your server is configured to send emails; you may need to configure SMTP settings for the mail or sendmail command to work correctly.

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

上面回答部分来自ChatGPT-3.5,没有进行正确性的交叉校验。

Conda

conda

Anaconda和Miniconda都是针对数据科学和机器学习领域的Python发行版本,它们包含了许多常用的数据科学包和工具,使得安装和管理这些包变得更加简单。

解决了几个痛点:

  1. 不同python环境的切换(类似VirtualEnv)
  2. 高效的包管理工具(类似pip,特别是在Windows上好用)

anaconda

Anaconda是一个全功能的Python发行版本,由Anaconda, Inc.(前称Continuum Analytics)提供。

  • 它包含了Python解释器以及大量常用的数据科学、机器学习和科学计算的第三方库和工具,如NumPy、Pandas、Matplotlib、SciPy等。
  • Anaconda还包含一个名为Conda的包管理器,用于安装、更新和管理这些库及其依赖项。
  • Anaconda发行版通常较大(500MB),因为它预装了许多常用的包,适用于不希望从头开始搭建环境的用户。

Miniconda

Miniconda是Anaconda的轻量级版本(50MB),它也由Anaconda, Inc.提供。

  • 与Anaconda不同,Miniconda只包含了Python解释器和Conda包管理器,没有预装任何其他包。这意味着用户可以根据自己的需求手动选择要安装的包,从而实现一个精简而高度定制化的Python环境。
  • 对于希望从零开始构建数据科学环境或需要更细粒度控制的用户,Miniconda是一个很好的选择。

Install miniconda

According to the official website,

wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh
# choose local path to install, maybe ~/.local
# init = yes, will auto modified the .zshrc to add the miniconda to PATH

# If you'd prefer that conda's base environment not be activated on startup,
#    set the auto_activate_base parameter to false:
conda config --set auto_activate_base false

you need to close all terminal(all windows in one section including all split windows), and reopen a terminal will take effect;

Python on windows

ref

创建虚拟环境

使用以下命令创建一个名为"myenv"的虚拟环境(您可以将"myenv"替换为您喜欢的环境名称):

conda create --name myenv python=3.8

# list existed env
conda env list

激活环境

conda activate name

环境包的生成和使用

conda list -e > requirements.txt
conda install --yes --file requirements.txt

pyproject.toml

$ pip install .
ERROR: Directory '.' is not installable. Neither 'setup.py' nor 'pyproject.toml' found.

在conda命令无效时使用pip命令来代替

while read requirement; do conda install --yes $requirement || pip install $requirement; done < requirements.txt

The double pipe (“||”) is a control operator that represents the logical OR operation. It is used to execute a command or series of commands only if the previous command or pipeline has failed or has returned a non-zero status code.

保存和复制conda环境的配置

conda env export > freeze.yml
conda env create -f freeze.yml

复制(fork)已有的环境

conda create -n 新环境名称 --clone 原环境名称 --copy

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

https://blog.csdn.net/Mao_Jonah/article/details/89502380

Linux Terminal

导言

对程序员来说,一个好用、易用的terminal,就是和军人手上有把顺手的好枪一样。

基础知识

用户的环境变量和配置文件

在Linux系统中,用户的环境变量和配置文件可以在不同的节点生效。以下是这些文件的功能和它们生效的时机:

  1. /etc/environment:

    • 功能: 设置系统范围的环境变量。
    • 生效时机: 在用户登录时读取,但不会执行shell命令。它主要用于设置变量,如PATH、LANG等。
  2. /etc/profile:

    • 功能: 为系统的每个用户设置环境信息。
    • 生效时机: 当用户登录时,会读取并执行该文件中的配置。它是针对登录shell(例如,通过终端登录或ssh登录)的。
  3. /etc/profile.d/:

    • 功能: 存放多个脚本,这些脚本会被/etc/profile读取和执行。
    • 生效时机: 与/etc/profile相同,登录shell时执行。它使得系统管理员可以将不同的配置分散到多个文件中管理。
  4. /etc/bash.bashrc:

    • 功能: 为所有用户设置bash shell的配置。
    • 生效时机: 对于非登录shell(例如,打开一个新的终端窗口)时会读取并执行。
  5. ~/.profile:

    • 功能: 为单个用户设置环境信息。
    • 生效时机: 用户登录时读取并执行,主要针对登录shell。
  6. ~/.bashrc:

    • 功能: 为单个用户配置bash shell的设置。
    • 生效时机: 用户打开一个新的bash shell(非登录shell)时读取并执行。

总结

  • /etc/environment/etc/profile 主要用于系统范围的环境变量设置,前者不会执行shell命令,后者会执行。
  • /etc/profile.d/ 中的脚本作为 /etc/profile 的扩展,用于更灵活的管理配置。
  • /etc/bash.bashrc 适用于所有用户的bash配置,但只针对非登录shell。
  • ~/.profile~/.bashrc 适用于单个用户,前者用于登录shell,后者用于非登录shell。

通过这些文件,系统和用户可以灵活地设置和管理环境变量和shell配置,以满足不同的需求和使用场景。

\n \r 回车 换行
符号 ASCII码 意义
\n 10 换行NL: 本义是光标往下一行(不一定到下一行行首),n的英文newline,控制字符可以写成LF,即Line Feed
\r 13 回车CR: 本义是光标重新回到本行开头,r的英文return,控制字符可以写成CR,即Carriage Return

在不同的操作系统这几个字符表现不同:

  1. 在WIN系统下,这两个字符就是表现的本义,
  2. 在UNIX类系统,换行\n就表现为光标下一行并回到行首,
  3. 在MAC上,\r就表现为回到本行开头并往下一行,至于ENTER键的定义是与操作系统有关的。通常用的Enter是两个加起来。
\n: UNIX 系统行末结束符
\n\r: window 系统行末结束符
\r: MAC OS 系统行末结束符

终端命令行代理

在任意层级的SHELL配置文件里添加

export http_proxy=http://yourproxy:port
export https_proxy=http://yourproxy:port

写成bashrc的脚本命令

#YJH proxy
export proxy_addr=localhost
export proxy_http_port=7890
export proxy_socks_port=7890
function set_proxy() {
   export http_proxy=http://$proxy_addr:$proxy_http_port #如果使用git 不行,这两个http和https改成socks5就行
   export https_proxy=http://$proxy_addr:$proxy_http_port
   export all_proxy=socks5://$proxy_addr:$proxy_socks_port
   export no_proxy=127.0.0.1,.huawei.com,localhost,local,.local 
}
function unset_proxy() {
   unset http_proxy
   unset https_proxy
   unset all_proxy
}
function test_proxy() {
   curl -v -x http://$proxy_addr:$proxy_http_port https://www.google.com | egrep 'HTTP/(2|1.1) 200'
   # socks5h://$proxy_addr:$proxy_socks_port
}
# set_proxy # 如果要登陆时默认启用代理则取消注释这句

常用命令

check process create time

ps -eo pid,lstart,cmd |grep bhive
date

kill all process by name

 sudo ps -ef | grep 'bhive-re' | grep -v grep | awk '{print $2}' | sudo xargs -r kill -9

常见问题

鼠标滚轮输出乱码

滚轮乱码,是tmux set mouse on的原因

进入tmux后退出,并运行reset即可

sudo后找不到命令

当你使用sudo去执行一个程序时,处于安全的考虑,这个程序将在一个新的、最小化的环境中执行,也就是说,诸如PATH这样的环境变量,在sudo命令下已经被重置成默认状态了。

添加所需要的路径(如 /usr/local/bin)到/etc/sudoers文件"secure_path"下

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
在用python使用curses写多进程进度条的时候,混乱输出

解决办法如下:

stdscr = curses.initscr() # 不要设置为全局变量
# 而且 使用set_win unset_win 保持区域换行的行为

参考文献

Zsim-tlb: bug

bug

zsim-tlb simulate in icarus0

pinbin: build/opt/zsim.cpp:816: LEVEL_BASE::VOID VdsoCallPoint(LEVEL_VM::THREADID): Assertion `vdsoPatchData[tid].level' failed.
Pin app terminated abnormally due to signal 6.

locate error

VOID VdsoCallPoint(THREADID tid) {
    //level=0,invalid
    assert(vdsoPatchData[tid].level);
    vdsoPatchData[tid].level++;
    // info("vDSO internal callpoint, now level %d", vdsoPatchData[tid].level); //common
}
  • vDSO (virtual dynamic shared object) is a kernel machanism for exporting a carefully set kernel space routines (eg. not secret api, gettid() and gettimeofday()) to user spapce to eliminate the performance penalty of user-kernel mode switch according to wiki. vDSO
  • You can use some __vdso_getcpu() C library, and kernel will auto move it to user-space
  • vDSO overcome vsyscall(first linux-kernel machanism to accelerate syscall) drawback.
  • In zsim, vDSO have only four function enum VdsoFunc {VF_CLOCK_GETTIME, VF_GETTIMEOFDAY, VF_TIME, VF_GETCPU};

vDSO simulate part

// Instrumentation function, called for EVERY instruction
VOID VdsoInstrument(INS ins) {
    ADDRINT insAddr = INS_Address(ins); //get ins addr
    if (unlikely(insAddr >= vdsoStart && insAddr < vdsoEnd)) {
        //INS is vdso syscall
        if (vdsoEntryMap.find(insAddr) != vdsoEntryMap.end()) {
            VdsoFunc func = vdsoEntryMap[insAddr];
            //call VdsoEntryPoint function
            //argv are: tid ,func(IARG_UINT32),arg0(LEVEL_BASE::REG_RDI),arg1(LEVEL_BASE::REG_RSI) 
            INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) VdsoEntryPoint, IARG_THREAD_ID, IARG_UINT32, (uint32_t)func, IARG_REG_VALUE, LEVEL_BASE::REG_RDI, IARG_REG_VALUE, LEVEL_BASE::REG_RSI, IARG_END);
        } else if (INS_IsCall(ins)) {   //call instruction
            INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) VdsoCallPoint, IARG_THREAD_ID, IARG_END);
        } else if (INS_IsRet(ins)) {    //Ret instruction
            INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) VdsoRetPoint, IARG_THREAD_ID, IARG_REG_REFERENCE, LEVEL_BASE::REG_RAX /* return val */, IARG_END);
        }
    }

    //Warn on the first vsyscall code translation
    if (unlikely(insAddr >= vsyscallStart && insAddr < vsyscallEnd && !vsyscallWarned)) {
        warn("Instrumenting vsyscall page code --- this process executes vsyscalls, which zsim does not virtualize!");
        vsyscallWarned = true;
    }
}

INS_Address is from pin-kit, but INS_InsertCall is pin api.

try:

.level is just show the level of nested vsyscall. I think comment the assert which trigerd when callfunc before entryfunc is just fun.

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

上面回答部分来自ChatGPT-3.5,没有进行正确性的交叉校验。