From d23724affb584f483400e8aa8ff334c723f92a88 Mon Sep 17 00:00:00 2001 From: Charles Chan Date: Sat, 17 Feb 2024 22:15:48 +0800 Subject: [PATCH] add --- _posts/2023-12-26-avdecc.md | 39 +++--- _posts/2024-01-23-sudo-kill-pgrp.md | 58 ++++++++ _posts/2024-01-26-search-string-from-bin.md | 16 +++ _posts/2024-02-05-lcov-prefix.md | 145 ++++++++++++++++++++ about.md | 5 + public/js/index.js | 35 +++-- 6 files changed, 266 insertions(+), 32 deletions(-) create mode 100644 _posts/2024-01-23-sudo-kill-pgrp.md create mode 100644 _posts/2024-01-26-search-string-from-bin.md create mode 100644 _posts/2024-02-05-lcov-prefix.md diff --git a/_posts/2023-12-26-avdecc.md b/_posts/2023-12-26-avdecc.md index 7c3cb03..82398e5 100644 --- a/_posts/2023-12-26-avdecc.md +++ b/_posts/2023-12-26-avdecc.md @@ -97,19 +97,19 @@ ADP 报文的发送形式为多播。 * ACMP **_ AVDECC Connection Management Protocol - ** ACMP Controller state machine + ** ACMP Controller \nstate machine ***_ 描述了 AVDECC 在 ACMP 会话中的主动参与方式。 ***_ AVDECC 控制器可以独立于这些状态机来监视所有接收到的 ACMP 消息,\n用于跟踪网络上的连接状态。 *** Fast connect - ****_ 启动过程中,Listener 根据预存的状态直接向 Talker 发起连接 + ****_ 启动过程中,Listener 根据预存的状态直接向\n Talker 发起连接 *** Fast disconnect - ****_ 关机过程中,Listener 直接向 Talker 通知断开连接 + ****_ 关机过程中,Listener 直接向 Talker 通知\n断开连接 *** Controller connect - ****_ 由 Controller 通知 Listener 向 Talker 发送建立连接请求 + ****_ 由 Controller 通知 Listener 向 Talker\n 发送建立连接请求 *** Controller disconnect - ****_ 由 Controller 通知 Listener 向 Talker 发送断开连接请求 - ** ACMP Listener State Machine - ** ACMP Talker State Machine + ****_ 由 Controller 通知 Listener 向 Talker\n 发送断开连接请求 + ** ACMP Listener \nState Machine + ** ACMP Talker \nState Machine @endmindmap ``` @@ -133,23 +133,22 @@ ADP 报文的发送形式为多播。 *** AEM Commands ****_ 用于发送与 AVDECC 实体模型交互的实体模型命令。 *** AEM Responses - ****_ 来自 AVDECC 实体,指示成功或失败并返回对应请求信息的实体模型响应。 - ** State Machine + ****_ 来自 AVDECC 实体,\n指示成功或失败并返回对应请求信息的实体模型响应。 *** AEM Entity State Machine ****_ 接受命令、处理命令并回复 *** AEM Controller State Machine ****_ 发送命令并处理回复 - *** Address Access Entity State Machine - ****_ 处理地址访问命令的状态机。\n用于读取、写入或处理启动消息中包含的 TLV 数据。 - ****_ 这里的地址可以是寄存器地址,甚至用于固件升级功能。\n或者制定地址指针开始执行程序。 - ****_ 该命令从 AVDECC 控制器发送到目标 AVDECC 实体。 - *** Legacy AV/C Controller State Machine - ****_ 处理遵循 IEEE 1394 AV/C 语义的传统 AV/C 命令/答复 的状态机。 - *** Vendor Unique Controller State Machine - ****_ 处理供应商自定义的 命令/答复 的状态机。 - *** HDCP APM Entity State Machine - ****_ 处理 HDCP APM 命令、用于传输 HDCP IIA 认证协议消息\n或 HDCP IIA 认证协议消息的一部分的状态机。 - ****_ 该命令从 AVDECC 控制器发送到目标 AVDECC 实体。 + ** Address Access Entity State Machine + ***_ 处理地址访问命令的状态机。\n用于读取、写入或处理启动消息中包含的 TLV 数据。 + ***_ 这里的地址可以是寄存器地址,甚至用于固件升级功能。\n或者制定地址指针开始执行程序。 + ***_ 该命令从 AVDECC 控制器发送到目标 AVDECC 实体。 + ** Legacy AV/C Controller State Machine + ***_ 处理遵循 IEEE 1394 AV/C 语义的传统 AV/C 命令/答复。 + ** Vendor Unique Controller State Machine + ***_ 处理供应商自定义的 命令/答复。 + ** HDCP APM Entity State Machine + ***_ 处理 HDCP APM 命令、用于传输 HDCP IIA 认证协议消息\n或 HDCP IIA 认证协议消息的一部分。 + ***_ 该命令从 AVDECC 控制器发送到目标 AVDECC 实体。 @endmindmap ``` diff --git a/_posts/2024-01-23-sudo-kill-pgrp.md b/_posts/2024-01-23-sudo-kill-pgrp.md new file mode 100644 index 0000000..f440614 --- /dev/null +++ b/_posts/2024-01-23-sudo-kill-pgrp.md @@ -0,0 +1,58 @@ +--- +layout: post +title: 同一脚本内,kill 通过 sudo 启动的进程 +tag: [Shell] +categories: [Linux] +--- + + + +# 问题 + +简单的说,如下脚本中的`kill`是不会生效的。 + +```bash +#!/bin/bash +set -x +sudo sleep 10 & +PID=$! + +sleep 2 +sudo kill $PID + +sleep 1 +ps aux | grep sleep +``` + +参考: [Why does kill not work from script, but does work from terminal?](https://unix.stackexchange.com/a/625478) 。如果我没理解错的话,原因是: + +`sudo` 不能用来 `kill` 同一个进程组内的其他进程。 + +# 解决方案 + +这里,使用 `setsid` 来重置 `sleep` 进程的进程组(注意:不是 `sudo sleep` )。 + +然后,借助曾经在《 [Shell脚本中,等待所有子进程/孙进程退出](../wait-child-grandchild-quit/) 》中使用过的方法,通过查询 `sudo sleep` 的子进程的方式 `kill` 由 `sudo` 启动的 `sleep` 进程。 + +接下来,由于子进程退出(被 `kill`),`sudo sleep` 进程也会自动退出。 + + +```bash +#!/bin/bash +set -x + +sudo setsid sleep 10 & +PID=$! + +sleep 2 +WPIDs=($(ps -eo pid,ppid \ + | awk -v ppid=$PID '{if($2==ppid && $1!=ppid){print $1}}')) +for pid in ${WPIDs[@]} ; do + if ps -p $pid > /dev/null ; then + sudo kill $pid + fi +done + +sleep 1 +ps aux | grep sleep +``` diff --git a/_posts/2024-01-26-search-string-from-bin.md b/_posts/2024-01-26-search-string-from-bin.md new file mode 100644 index 0000000..8b0b447 --- /dev/null +++ b/_posts/2024-01-26-search-string-from-bin.md @@ -0,0 +1,16 @@ +--- +layout: post +title: 筛查二进制文件中是否包涵敏感字符 +tag: [Shell] +categories: [Linux] +--- + + + +在对外发布的二进制文件中筛查敏感常量信息。比如 LOG 中包涵了设备型号。 + +``` +find /root/path/to/releases -type f \ + -exec sh -c "file -i '{}' | grep -q 'charset=binary'" \; -print \ + | xargs -x strings -f | grep -i +``` diff --git a/_posts/2024-02-05-lcov-prefix.md b/_posts/2024-02-05-lcov-prefix.md new file mode 100644 index 0000000..9e5f2b1 --- /dev/null +++ b/_posts/2024-02-05-lcov-prefix.md @@ -0,0 +1,145 @@ +--- +layout: post +title: 在非编译环境中运行测试程序并获取正确的覆盖率报告 +tag: [GCC,Gcov] +categories: [Program] +--- + +本文针对`GCOV_PREFIX`和`GCOV_PREFIX_STRIP`的使用进行一些记录。 + + + +首先,准备一个简单的 C 语言程序作为测试目标。 + +```c +#include +#include + +int foo(int a) +{ + return a * a; +} + +int main(int argc, char const *argv[]) +{ + printf("%d\n", foo(atoi(argv[1]))); + return 0; +} +``` + +在最简单的情况下,我们的情况会类似于下面的脚本。 +即编译环境和运行环境都在一起。 + +这种情况下,只要参数设置没有问题,就可以简单的获取对应的覆盖率报告。 + + +```bash +#!/bin/bash + +gcc main.c -o test -lgcov -coverage +./test 2 + +lcov -c -d $(pwd) -o test.info +genhtml test.info -o doc +``` + +但是,很多情况下,我们都需要将测试程序移动到其他环境中运行。 +比如下面的脚本模拟了在`Docker`中运行测试程序的情况。 + +简单的运行一下,我们会发现,覆盖率报告生成失败了。 +原因是, `lcov` 找不到 `.gcda` 文件。 + + +```bash +#!/bin/bash + +gcc main.c -o test -lgcov -coverage + +docker run -v $(pwd):/home/test \ + ubuntu:20.04 /home/test/test 2 + +lcov -c -d $(pwd) -o test.info +genhtml test.info -o doc +``` + +解决的方法也很简单。在目标环境中设置`GCOV_PREFIX`和`GCOV_PREFIX_STRIP`这两个环境变量。 +其中: + +* `GCOV_PREFIX` 是测试程序运行的位置。 +* `GCOV_PREFIX_STRIP` 是编译测试程序时,源代码所在路径的深度。 + + +```bash +#!/bin/bash + +gcc main.c -o test -lgcov -coverage + +echo "#!/bin/bash" > startup.sh +echo "export GCOV_PREFIX=/home/test" >> startup.sh +echo "export GCOV_PREFIX_STRIP=\$(echo $(pwd) | awk -F\"/\" '{print NF-1}')" \ + >> startup.sh +echo "/home/test/test 2" >> startup.sh +chmod +x startup.sh +docker run -v $(pwd):/home/test -w /home/test \ + ubuntu:20.04 /home/test/startup.sh + +lcov -c -d $(pwd) -o test.info +genhtml test.info -o doc +``` + +上述例子其实还不够精准的描述更加复杂的情况。 +例如,当我们需要在多个`Docker`中并行运行同一段代码时(这种情况常见于动态链接库), +同时运行的程序会竞争`.gcda`文件。引发写冲突破坏`.gcda`文件。 +为了避免类似的问题,我们可能需要将测试程序拷贝多份。 + +参照下面的脚本,我们将编译出来的测试程序移动到了源代码以外的路径(`new`),去执行 +(脚本并没有模拟并行运行的情况,毕竟测试程序太简单了,一瞬间就退出了)。 + +这种情况下,直接执行测试程序,就会由于缺少信息而无法生成覆盖率报告。 +这些信息其实是保存在`.gcno`文件中。 + +参照下面的脚本,将`main.gcno`同样复制到新的路径下,然后再次运行测试程序。 +覆盖率报告可以顺利的生成了。 + + +```bash +#!/bin/bash + +gcc main.c -o test -lgcov -coverage +install -d new +install test new + +echo "#!/bin/bash" > new/startup.sh +echo "export GCOV_PREFIX=/home/test" >> new/startup.sh +echo "export GCOV_PREFIX_STRIP=\$(echo $(pwd) | awk -F\"/\" '{print NF-1}')" \ + >> new/startup.sh +echo "/home/test/test 2" >> new/startup.sh +chmod +x new/startup.sh + +cp main.gcno new/ +docker run -v $(pwd)/new:/home/test/ -w /home/test \ + ubuntu:20.04 /home/test/startup.sh + +lcov -c -d $(pwd)/new -o test.info +genhtml test.info -o doc +``` + +简单总结一下。 + +某工程代码的存放路径为`/path/to/proj`,其中有一个源文件存放在`a/b.c`。 +编译生成的`a.out`转移到目标系统的`/usr/bin`下运行。 + +此时,需要进行如下工作: + +* 将`/path/to/proj/a/b.gcno`复制到目标环境的`/usr/bin/a/b.gcno`; +* 设置环境变量`GCOV_PREFIX=/usr/bin`; +* 设置环境变量`GCOV_PREFIX_STRIP=3`。(`/path/to/proj`是三层)。 + +运行时,`a.out`会根据调试信息去寻找`/path/to/proj/a/b.gcno`。 +但是,由于设置了`GCOV_PREFIX`,这个目标会调整为`/usr/bin/path/to/proj/a/b.gcno`。 +然后,由于设置了`GCOV_PREFIX_STRIP`,将`/usr/bin/`后面的三级路径删除,变成了 +`/usr/bin/a/b.gcno`。 +在这里,`a.out`找到了我们提前复制进去的`b.gcno`文件。 +并在同样的位置生成`/usr/bin/a/b.gcda`文件。 + +有了`.gcno`和`.gcda`文件,就可以生成测试报告了。 diff --git a/about.md b/about.md index 18f7b7c..cb3967b 100644 --- a/about.md +++ b/about.md @@ -9,6 +9,11 @@ title: About ![](https://ghchart.rshah.org/zeerd) +本站的一些实时生成的图片是基于一个IPv6的HTTPS工具实现的。 +由于一些众所周知的原因,这个网站有时候连接会不够顺畅。 +这时候,会自动切换到一个基于IPv4的HTTP工具。 +这会导致浏览器显示链接不安全。暂时还没找到太好的替代方案。 + ## Base This is a blog based on [poole](https://github.com/poole) and [vrepinblog](https://github.com/vitalyrepin/vrepinblog) diff --git a/public/js/index.js b/public/js/index.js index 68e6ea2..75fab28 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -21,28 +21,39 @@ setInterval(() => { } }, 1000) -function DrawPlantUML(prefix) { +function DrawPlantUML(type) { var elements = document.getElementsByClassName('language-plantuml'); - for (var i=0, len=elements.length|0; i"; - elements[i].innerHTML = ""; - elements[i].className = "plantuml"; - elements[i].outerHTML = elements[i].outerHTML.replace(/code/g,"div"); + for (var i=elements.length-1, len=elements.length|-1; i>=0; i=i-1|-1) { + // if(elements[i] !== undefined) { + if(type == "IPv6") { + encoded = encodeURI("https://vultr6.zeerd.com/plantuml.php?uml=" + elements[i].innerHTML); + } + else { + encoded = encodeURI("http://vultr.zeerd.com/plantuml.php?uml=" + elements[i].innerHTML); + } + encoded = encoded.replace(/#/g, "%23"); + if(type == "IPv6") { + elements[i].innerHTML = ""; + } + else { + elements[i].innerHTML = "PlantUML"; + } + elements[i].outerHTML = elements[i].outerHTML.replace(/code/g,"div"); + elements[i].className = "plantuml"; + // } } } -let img = document.createElement('img'); +var img = document.createElement('img'); img.src = "https://vultr6.zeerd.com/1x1.png"; img.onload = function() { setInterval(() => { - DrawPlantUML("https://vultr6.zeerd.com"); + DrawPlantUML("IPv6"); }, 1000) }; img.onerror = function() { setInterval(() => { - DrawPlantUML("http://vultr.zeerd.com"); + DrawPlantUML("IPv4"); }, 1000) };