-
Notifications
You must be signed in to change notification settings - Fork 4k
doc: add GitHub Copilot custom instructions #5499
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| ## Description | ||
|
|
||
| <!-- What does this PR do? Which problem does it solve? --> | ||
|
|
||
| ## Why this approach | ||
|
|
||
| <!-- Explain why you chose this approach over alternatives. --> | ||
|
|
||
| --- | ||
|
|
||
| ## Checklist | ||
|
|
||
| - [ ] Commit prefix matches changed area (e.g., `tools/toolname:`, `libbpf-tools/toolname:`, `src/cc:`, `doc:`, `build:`, `tests/python:`) | ||
| - [ ] Commit body explains **why** this change is needed | ||
|
|
||
| **For new tools only** | ||
| - [ ] Explains why this tool is needed and what existing tools cannot cover this use case | ||
| - [ ] Includes at least one real production use case | ||
| - [ ] Man page (`man/man8/`) with OVERHEAD and CAVEATS sections | ||
| - [ ] Example output file (`*_example.txt`) | ||
| - [ ] README.md entry added | ||
| - [ ] Smoke test added to `tests/python/test_tools_smoke.py` | ||
|
|
||
| --- | ||
|
|
||
| > **Note:** The maintainer may request a Copilot code review on this PR. | ||
| > AI feedback is advisory only — reply with your reasoning if you disagree; the maintainer decides. | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,54 @@ | ||||||
| # BCC Project — GitHub Copilot Instructions | ||||||
|
|
||||||
| BCC is a toolkit for creating efficient kernel tracing and manipulation programs using eBPF. Tools run in **mission-critical environments as root**. | ||||||
|
|
||||||
| ## Global Review Principles (Applied to all PRs) | ||||||
|
|
||||||
| ### Commit Message Format | ||||||
|
|
||||||
| ``` | ||||||
| <prefix>: <short summary> | ||||||
|
|
||||||
| <WHY this change is needed — not just what changed> | ||||||
| - Problem being solved | ||||||
| - Why this approach was chosen | ||||||
| ``` | ||||||
|
|
||||||
| **Prefixes:** `tools/toolname:`, `libbpf-tools/toolname:`, `src/cc:`, `build:`, `ci:`, `doc:`, `tests/python:` | ||||||
|
|
||||||
| ### Style Checks | ||||||
|
|
||||||
| - **Python:** `scripts/py-style-check.sh` (pycodestyle, ignore E123/E125/E126/E127/E128/E302) | ||||||
|
||||||
| - **Python:** `scripts/py-style-check.sh` (pycodestyle, ignore E123/E125/E126/E127/E128/E302) | |
| - **Python:** `scripts/py-style-check.sh` (runs `pycodestyle` ignoring E123/E125/E126/E127/E128/E302, and also fails on executable `tools/` and `examples/` Python files that don’t use the `#!/usr/bin/python` shebang) |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,66 @@ | ||||||
| --- | ||||||
| applyTo: "src/cc/**" | ||||||
| --- | ||||||
|
|
||||||
| # BCC Core Library Review Instructions | ||||||
|
|
||||||
| All BCC tools depend on this code — stability and backward compatibility are critical. | ||||||
|
|
||||||
| <CriticalRules> | ||||||
| - MUST NOT break public C++ APIs without a deprecation cycle. | ||||||
| - When changing a C++ function signature, MUST update `src/python/bcc/__init__.py` ctypes bindings. | ||||||
| - MUST NULL-check every `malloc()`, `calloc()`, `realloc()`, and `strdup()` call. | ||||||
|
Comment on lines
+10
to
+12
|
||||||
| - MUST use negative errno consistently for error returns. | ||||||
| - MUST guard all architecture-specific code with `#ifdef __x86_64__` / `#ifdef __aarch64__` etc. | ||||||
| </CriticalRules> | ||||||
|
|
||||||
| ## API & ABI Stability | ||||||
|
|
||||||
| - Deprecate gracefully: add `[[deprecated(...)]]` and a one-time `fprintf(stderr, "Warning: …")` in the old function body | ||||||
|
||||||
| - Deprecate gracefully: add `[[deprecated(...)]]` and a one-time `fprintf(stderr, "Warning: …")` in the old function body | |
| - Deprecate gracefully: use the project’s existing deprecation attribute (for example, `__attribute__((deprecated("…")))`) and a one-time `fprintf(stderr, "Warning: …")` in the old function body |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| --- | ||
| applyTo: "examples/**" | ||
| --- | ||
|
|
||
| # BCC Examples Review Instructions | ||
|
|
||
| Examples are **educational** — prioritize clarity over production robustness. | ||
|
|
||
| <CriticalRules> | ||
| - Focus on **one concept** per example; target **< 150 lines** total. | ||
| - Every major BPF step MUST have an inline comment explaining **why**, not just what. | ||
| - Header comment MUST describe the concept demonstrated and usage. | ||
| - Do NOT add complex argument parsing or production-grade error handling — it obscures the learning point. | ||
| - License header MUST be present. | ||
| </CriticalRules> | ||
|
|
||
| ## Required Header Comment | ||
|
|
||
| Every example must start with: | ||
| ``` | ||
| # example_name.py Brief one-line description | ||
| # Demonstrates: [what BCC/eBPF concept this shows] | ||
| # USAGE: example_name.py | ||
| # Copyright [year] [author] / Licensed under Apache 2.0 | ||
| ``` | ||
|
|
||
| ## Pedagogical Quality | ||
|
|
||
| - One BCC concept per example; builds naturally on simpler ones | ||
| - Clear learning objective; do not mix maps + arrays + perf buffers + USDT in one example | ||
| - Output is labeled (column headers); explain what's being traced | ||
| - Minimal error handling: catch `BPF()` failure and `KeyboardInterrupt` only | ||
|
|
||
| ## Kernel Compatibility | ||
|
|
||
| - Note kernel requirements in a comment when using features requiring ≥ 4.x | ||
| - Use `BPF.kernel_struct_has_field()` for runtime field detection; never hard-code kernel versions | ||
|
|
||
| ## File Organization | ||
|
|
||
| - `networking/` — network-related examples | ||
| - `tracing/` — kernel/userspace tracing | ||
| - `usdt_sample/` — USDT examples | ||
| - `lua/` — Lua API examples | ||
| - `cpp/` — C++ API examples | ||
|
|
||
| ## What Examples Do NOT Require | ||
|
|
||
| Unlike `tools/`, examples do **not** need: | ||
| - Man pages, `*_example.txt` files, README.md entries (optional) | ||
| - Comprehensive argparse argument handling | ||
| - Overhead documentation | ||
|
|
||
| ## Review Checklist | ||
|
|
||
| - [ ] ≤ 150 lines; focuses on a single BCC concept | ||
| - [ ] Inline comments explain each BPF step | ||
| - [ ] Header comment describes purpose and concept demonstrated | ||
| - [ ] License header present | ||
| - [ ] Output is labeled and explained | ||
| - [ ] Basic error handling present (BPF compile failure, KeyboardInterrupt) | ||
| - [ ] Correct subdirectory placement | ||
| - [ ] Python 3 compatible | ||
| - [ ] No undocumented external dependencies | ||
|
|
||
| ## Red Flags — Always Flag | ||
|
|
||
| 1. > 150 lines or mixes too many concepts (belongs in `tools/` instead) | ||
| 2. Missing inline comments on BPF logic | ||
| 3. No header comment describing the concept demonstrated | ||
| 4. Missing license header | ||
| 5. No output or unexplained/unlabeled output | ||
| 6. Python 2-only code (`print "..."`, `except Exception, e:`) | ||
| 7. Undocumented external Python dependencies |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| --- | ||
| applyTo: ".github/instructions/*.instructions.md" | ||
| --- | ||
|
|
||
| # Authoring BCC Instruction Files | ||
|
|
||
| These files define Copilot review rules for the BCC project. | ||
| When editing them, follow the steps below to avoid writing rules that contradict | ||
| the actual codebase. | ||
|
|
||
| ## Before Writing or Updating Any Rule | ||
|
|
||
| 1. **API / function examples** — read the actual source before writing: | ||
| - Python BCC API → check `src/python/bcc/table.py` | ||
| - BPF helper signatures → check `libbpf-tools/*.bpf.c` examples | ||
| - Userspace libbpf patterns → check `libbpf-tools/*.c` examples | ||
|
|
||
| 2. **Conventions (shebang, imports, prefixes, etc.)** — sample the real files: | ||
| - `tools/*.py` for Python conventions (shebang) | ||
| - `libbpf-tools/*.c` / `*.bpf.c` for C conventions | ||
| - `git log --oneline origin/master | head -30` for commit prefix convention (format: `subsystem/toolname:`) | ||
|
|
||
| 3. **Do not invent or assume** an API method, macro, or convention exists — | ||
| verify it in the repo first. | ||
|
|
||
| ## Scope of Each Instructions File | ||
|
|
||
| | File | `applyTo` | Triggers when… | | ||
| |------|-----------|----------------| | ||
| | `tools.instructions.md` | `tools/**/*.py` | editing a Python tool | | ||
| | `libbpf-tools.instructions.md` | `libbpf-tools/**/*` | editing a libbpf tool | | ||
| | `core.instructions.md` | `src/cc/**` | editing BCC core library | | ||
| | `examples.instructions.md` | `examples/**` | editing an example | | ||
| | `instructions.instructions.md` | `.github/instructions/*.instructions.md` | editing these rule files | | ||
|
|
||
| ## Style | ||
|
|
||
| - Keep `<CriticalRules>` short — Copilot has a ~4,000 character review window | ||
| - One rule per bullet; no redundancy across files | ||
| - Flag blockers explicitly; use 🟡 Warning for non-blockers |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| --- | ||
| applyTo: "libbpf-tools/**/*" | ||
| --- | ||
|
|
||
| # libbpf-tools (CO-RE) Review Instructions | ||
|
|
||
| These are CO-RE (Compile Once - Run Everywhere) tools using libbpf. | ||
|
|
||
| <CriticalRules> | ||
| - MUST use `vmlinux.h` for kernel types — do NOT redefine structs manually. | ||
| - MUST use `BPF_CORE_READ` (or `BPF_CORE_READ_USER` for user-space pointers) | ||
| for kernel struct field access — no direct `task->pid` style access. | ||
| - MUST NULL-check every BPF map lookup result before dereferencing. | ||
| - MUST NULL-check every `malloc()`, `calloc()`, `realloc()`, and `strdup()` in userspace C. | ||
| - MUST bounds-check every array index before access. | ||
| - BPF functions: flag if stack usage appears to approach or exceed 512 bytes (eBPF verifier hard limit). | ||
| - Use `bpf_core_field_exists()` for kernel version compatibility — never `#if LINUX_VERSION_CODE`. | ||
| - Use split lifecycle: `__open()` → configure rodata/map sizes → `__load()` → `__attach()`. | ||
| Flag `open_and_load()` if rodata fields or map max_entries are configured before load. | ||
| - Check return values of ALL attachment calls (`bpf_program__attach_*`). | ||
| - Do NOT use old-style map definitions (`bpf_map_def SEC("maps")`). | ||
| - Do NOT use hard-coded kernel version numbers or struct offsets. | ||
| - Do NOT create duplicate BPF programs with identical logic — use `bpf_program__set_attach_target()` instead. | ||
| - When providing both fentry and kprobe fallback paths: both paths must attach to the same | ||
| set of kernel functions. Use `bpf_program__set_attach_target()` in the kprobe path to | ||
| match the fentry path's attach targets. | ||
| </CriticalRules> | ||
|
|
||
| ## libbpf Object Lifecycle | ||
|
|
||
| - Always split: `__open()` → set rodata/map config → `__load()` → `__attach()` | ||
| - Flag any use of `open_and_load()` where rodata or map `max_entries` are configured | ||
| - Check all return values; use `goto cleanup` pattern | ||
| - All resources (skel, FDs, links) freed on all exit paths including errors | ||
|
|
||
| ## BPF Memory Safety | ||
|
|
||
| - NULL-check every `bpf_map_lookup_elem()` result before dereferencing | ||
| - Bounds-check every array index: `if (idx >= MAX_ENTRIES) return 0;` | ||
| - Check `bpf_probe_read_kernel()` return value: `if (ret < 0) return 0;` | ||
| - Keep per-function BPF stack usage well under 512 bytes; use per-CPU maps for large structs | ||
| - String reads: always use bounded helpers (`bpf_probe_read_kernel_str`, `bpf_get_current_comm`) | ||
|
|
||
| ## Userspace Rules | ||
|
|
||
| - Output: default **< 80 characters wide** | ||
| - Error messages: clear, actionable, include `strerror(errno)` where applicable | ||
| - Map FD: check `bpf_map__fd()` result is ≥ 0 before use | ||
| - Use existing helpers (`trace_helpers.h`, `map_helpers.h`) — don't duplicate | ||
|
|
||
| ## Required Files (New Tools) | ||
|
|
||
| ### Code | ||
| 1. `libbpf-tools/tool.bpf.c` — BPF program | ||
| 2. `libbpf-tools/tool.c` — userspace program | ||
| 3. `libbpf-tools/tool.h` — shared header (if needed) | ||
| 4. Makefile entry for skeleton generation | ||
|
|
||
| ### Documentation (enforce as blocker) | ||
| 5. `man/man8/tool.8` — with **OVERHEAD** and **CAVEATS** sections | ||
| 6. `README.md` — entry added | ||
| 7. `libbpf-tools/tool_example.txt` — example output *(recommended; may be omitted if an | ||
| equivalent Python tools/ example already exists)* | ||
|
|
||
| ## Review Checklist | ||
|
|
||
| - [ ] CO-RE: `vmlinux.h` used; `BPF_CORE_READ` family for all kernel struct access | ||
| - [ ] Lifecycle: split open → configure → load → attach (flag premature `open_and_load`) | ||
| - [ ] BPF memory safety: NULL checks after map lookups, bounds checks, stack well under 512 bytes | ||
| - [ ] Userspace: NULL checks after all `malloc`/`calloc`/`realloc`/`strdup` | ||
| - [ ] All attach/map FD return values checked | ||
| - [ ] Resources freed on all paths (`goto cleanup`) | ||
| - [ ] BTF-style map definitions (no `bpf_map_def`) | ||
| - [ ] No hard-coded kernel versions or offsets | ||
| - [ ] No duplicate BPF programs; fentry and kprobe paths cover same attach targets | ||
| - [ ] Output < 80 chars wide | ||
| - [ ] Makefile skeleton generation entry present | ||
| - [ ] Documentation: man page + README entry (new tools); example file recommended | ||
|
|
||
| ## References | ||
|
|
||
| - [libbpf Documentation](https://github.com/libbpf/libbpf) | ||
| - [BPF CO-RE Reference](https://nakryiko.com/posts/bpf-portability-and-co-re/) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| --- | ||
| applyTo: "tools/**/*.py" | ||
| --- | ||
|
|
||
| # BCC Tools (Python/BCC API) Review Instructions | ||
|
|
||
| Tools run in **mission-critical environments as root** — correctness and safety are mandatory. | ||
|
|
||
| <CriticalRules> | ||
| - BPF C code: MUST NULL-check every `map.lookup(&key)` result before dereferencing. | ||
| - BPF C code: MUST bounds-check every array index before access. | ||
| - BPF C code: flag if stack usage appears to approach or exceed 512 bytes (eBPF verifier hard limit). | ||
| - Default output MUST be under 80 characters wide. | ||
| - New tools MUST include man page (`man/man8/`) with **OVERHEAD** and **CAVEATS** sections. | ||
| </CriticalRules> | ||
|
|
||
| ## BCC API Safety | ||
|
|
||
| - Map lookup: use `table[key]` with `try/except KeyError`, or `table.get(key)` — check result is not `None` before use | ||
| - BPF C macro `map.lookup(&key)` returns a pointer — NULL means key not found; always guard before dereference | ||
| - Prefer map-based aggregation over per-event output for high-frequency events; filter in BPF, not Python | ||
|
|
||
| ## Required Documentation (New Tools) | ||
|
|
||
| 1. `man/man8/toolname.8` — with **OVERHEAD** and **CAVEATS** sections | ||
| 2. `tools/toolname_example.txt` — example output | ||
| 3. `README.md` — entry added | ||
| 4. `tests/python/test_tools_smoke.py` — smoke test entry | ||
|
|
||
| ## Kernel Compatibility | ||
|
|
||
| - Use `BPF.kernel_struct_has_field()` for runtime struct field detection — never hard-code kernel version numbers | ||
| - New options must not break existing default behavior |
Uh oh!
There was an error while loading. Please reload this page.