Skip to content

Commit

Permalink
add
Browse files Browse the repository at this point in the history
  • Loading branch information
zeerd committed Feb 17, 2024
1 parent 3c36eca commit d23724a
Show file tree
Hide file tree
Showing 6 changed files with 266 additions and 32 deletions.
39 changes: 19 additions & 20 deletions _posts/2023-12-26-avdecc.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,19 +97,19 @@ ADP 报文的发送形式为多播。
</style>
* 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
```

Expand All @@ -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
```

Expand Down
58 changes: 58 additions & 0 deletions _posts/2024-01-23-sudo-kill-pgrp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
layout: post
title: 同一脚本内,kill 通过 sudo 启动的进程
tag: [Shell]
categories: [Linux]
---

<!--break-->

# 问题

简单的说,如下脚本中的`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
```
16 changes: 16 additions & 0 deletions _posts/2024-01-26-search-string-from-bin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
layout: post
title: 筛查二进制文件中是否包涵敏感字符
tag: [Shell]
categories: [Linux]
---

<!--break-->

在对外发布的二进制文件中筛查敏感常量信息。比如 LOG 中包涵了设备型号。

```
find /root/path/to/releases -type f \
-exec sh -c "file -i '{}' | grep -q 'charset=binary'" \; -print \
| xargs -x strings -f | grep -i <keyword>
```
145 changes: 145 additions & 0 deletions _posts/2024-02-05-lcov-prefix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
---
layout: post
title: 在非编译环境中运行测试程序并获取正确的覆盖率报告
tag: [GCC,Gcov]
categories: [Program]
---

本文针对`GCOV_PREFIX``GCOV_PREFIX_STRIP`的使用进行一些记录。

<!--break-->

首先,准备一个简单的 C 语言程序作为测试目标。

```c
#include <stdio.h>
#include <stdlib.h>

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`文件,就可以生成测试报告了。
5 changes: 5 additions & 0 deletions about.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
35 changes: 23 additions & 12 deletions public/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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<len; i=i+1|0) {
encoded = encodeURI(prefix + "/plantuml.php?uml=" + elements[i].innerHTML);
encoded = encoded.replace(/#/g, "%23");
// elements[i].innerHTML = "<img alt='DOT sample with plantuml' src='" + encoded + "'>";
elements[i].innerHTML = "<object type='image/svg+xml' style='width:100%;height:100%' data='"
+ encoded + "'></object>";
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 = "<object type='image/svg+xml' style='width:100%;height:100%' "
+ "data='" + encoded + "'></object>";
}
else {
elements[i].innerHTML = "<img alt='PlantUML' src='" + encoded + "'>";
}
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)
};

0 comments on commit d23724a

Please sign in to comment.