Skip to content

Commit

Permalink
Merge pull request #87 from tttturtle-russ/master
Browse files Browse the repository at this point in the history
profread: kernel/dev-tools/kcov.md
  • Loading branch information
mudongliang committed Jul 4, 2024
2 parents 08a1c01 + 6395513 commit 9ea07f6
Showing 1 changed file with 11 additions and 9 deletions.
20 changes: 11 additions & 9 deletions sources/kernel/dev-tools/kcov.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
---
status: translated
status: proofread
title: "KCOV: code coverage for fuzzing"
author: Linux Kernel Community
collector: mudongliang
collected_date: 20240421
translator: tttturtle-russ
translated_date: 20240421
proofreader: tttturtle-russ
proofread_date: 20240703
link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/dev-tools/kcov.rst
---

# KCOV: 用于模糊测试的代码覆盖率

KCOV 以一种适用于覆盖率引导的模糊测试的形式收集和暴露内核代码覆盖率信息。一个正在运行的内核的覆盖率数据可以通过 `kcov` 调试文件导出。覆盖率的收集是基于任务启用的,因此 KCOV 可以精确捕获单个系统调用的覆盖率。
KCOV 以一种适用于覆盖率引导的模糊测试的形式收集和暴露内核代码覆盖率信息。一个正在运行的内核的覆盖率数据可以通过 ``kcov`` 调试文件导出。覆盖率的收集是基于任务启用的,因此 KCOV 可以精确捕获单个系统调用的覆盖率。

要注意的是 KCOV 不是为了收集尽可能多的覆盖率数据。而是为了收集相对稳定的覆盖率,这是系统调用输入的函数。为了完成这个目标,它不收集软硬中断的覆盖率(除非移除覆盖率收集被启用,见下文)以及内核中固有的不确定部分的覆盖率(如调度器,锁定)

除了收集代码覆盖率,KCOV 还收集操作数比较的覆盖率。见操作数比较收集一节查看详细信息。
除了收集代码覆盖率,KCOV 还收集操作数比较的覆盖率。见 "操作数比较收集" 一节查看详细信息。

除了从系统调用处理器收集覆盖率数据,KCOV还从后台内核或软中断任务中执行的内核被标注的部分收集覆盖率。见“远程覆盖率收集一节查看详细信息。
除了从系统调用处理器收集覆盖率数据,KCOV 还从后台内核或软中断任务中执行的内核被标注的部分收集覆盖率。见 "远程覆盖率收集" 一节查看详细信息。

## 先决条件

Expand Down Expand Up @@ -222,19 +224,19 @@ KCOV 支持在如下上下文中收集远程覆盖率:
2. 局部内核后台任务。这些任务通常是由于用户空间进程与某些内核接口进行交互时产生的,并且通常在进程退出时会被停止(如,vhost 工作器)。
3. 软中断。

对于 \#1 和 \#3,必须选择一个独特的全局句柄并将其传递给对应的 `kcov_remote_start` 调用。一个用户空间进程必须将该句柄存储在 `kcov_remote_arg` 结构体的 `handle` 数组字段中并将其传递给 `KCOV_REMOTE_ENABLE`。这会将使用的 KCOV 设备附加到由此句柄引用的代码片段。多个全局句柄标识的不同代码片段可以一次性传递。
对于 \#1 和 \#3,必须选择一个独特的全局句柄并将其传递给对应的`kcov_remote_start` 调用。一个用户空间进程必须将该句柄存储在`kcov_remote_arg` 结构体的 `handle` 数组字段中并将其传递给`KCOV_REMOTE_ENABLE`。这会将使用的 KCOV 设备附加到由此句柄引用的代码片段。多个全局句柄标识的不同代码片段可以一次性传递。

对于 \#2,用户空间进程必须通过 `kcov_remote_arg` 结构体的 `common_handle` 字段 传递一个非零句柄。这个通用句柄将会被保存在当前 `task_struct` 结构体的 `kcov_handle` 字段中并且需要通过自定义内核代码的修改来传递给新创建的本地任务。这些任务需要在 `kcov_remote_start``kcov_remote_stop` 标注中依次使用传递过来的句柄。
对于 \#2,用户空间进程必须通过 `kcov_remote_arg` 结构体的 `common_handle` 字段传递一个非零句柄。这个通用句柄将会被保存在当前 `task_struct` 结构体的`kcov_handle` 字段中并且需要通过自定义内核代码的修改来传递给新创建的本地任务。这些任务需要在 `kcov_remote_start``kcov_remote_stop` 标注中依次使用传递过来的句柄。

KCOV 对全局句柄和通用句柄均遵循一个预定义的格式。每一个句柄都是一个 `u64` 整形 。当前,只有最高位和低四位字节被使用。第 4-7 字节是保留位并且值必须为 0。
KCOV 对全局句柄和通用句柄均遵循一个预定义的格式。每一个句柄都是一个 `u64` 整形。当前,只有最高位和低四位字节被使用。第 4-7 字节是保留位并且值必须为 0。

对于全局句柄,最高位的字节表示该句柄属于的子系统的标识。比如,KCOV 使用 `1` 表示 USB 子系统类型。全局句柄的低 4 字节表示子系统中任务实例的标识。比如,每一 个 `hub_event` 工作器使用 USB 总线号作为任务实例的标识。
对于全局句柄,最高位的字节表示该句柄属于的子系统的标识。比如,KCOV 使用 `1`表示 USB 子系统类型。全局句柄的低 4 字节表示子系统中任务实例的标识。比如,每一个 `hub_event` 工作器使用 USB 总线号作为任务实例的标识。

对于通用句柄,使用一个保留值 `0` 作为子系统标识,因为这些句柄不属于一个特定的子系统。通用句柄的低 4 字节用于识别有用户进程生成的所有本地句柄的集合实例,该进程将通用句柄传递给 `KCOV_REMOTE_ENABLE`

实际上,如果只从系统中的单个用户空间进程收集覆盖率,那么可以使用任意值作为通用句柄的实例标识。然而,如果通用句柄被多个用户空间进程使用,每个进程必须使用唯一的实例标识。一个选择是使用进程标识作为通用句柄实例的标识。

下面的程序演示了如何使用 KCOV 从一个由进程产生的本地任务和处理 USB 总线的全局 任务 \#1 收集覆盖率:
下面的程序演示了如何使用 KCOV 从一个由进程产生的本地任务和处理 USB 总线的全局任务 #1 收集覆盖率:

``` c
/* 包含和上文一样的头文件和宏定义。 */
Expand Down

0 comments on commit 9ea07f6

Please sign in to comment.