Skip to content

Commit 15bb04e

Browse files
authored
Build and test on i686 (#43)
1 parent 14e173d commit 15bb04e

File tree

4 files changed

+114
-37
lines changed

4 files changed

+114
-37
lines changed

.github/workflows/build.yml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,70 @@ jobs:
7676
--object target/debug/pfiles --object target/debug/plgrp --object target/debug/prun \
7777
--object target/debug/psig --object target/debug/pstop --object target/debug/ptree \
7878
--object target/debug/pwait
79+
80+
build-i686:
81+
name: Build (i686)
82+
runs-on: ubuntu-24.04
83+
permissions:
84+
contents: read
85+
env:
86+
PKG_CONFIG_ALLOW_CROSS: 1
87+
PKG_CONFIG_PATH: /usr/lib/i386-linux-gnu/pkgconfig
88+
CARGO_BUILD_TARGET: i686-unknown-linux-gnu
89+
steps:
90+
- name: Check out
91+
uses: actions/checkout@v6
92+
93+
- name: Install i686 cross-compilation dependencies
94+
run: |
95+
sudo dpkg --add-architecture i386
96+
sudo apt-get update
97+
sudo apt-get install -y gcc-multilib libsystemd-dev:i386
98+
99+
- name: Install Rust i686 target
100+
run: rustup target add i686-unknown-linux-gnu
101+
102+
- name: Check formatting
103+
run: cargo fmt --all -- --check
104+
105+
- name: Check Markdown
106+
uses: DavidAnson/markdownlint-cli2-action@v22
107+
108+
- name: Run Clippy
109+
run: cargo clippy --all-targets --all-features
110+
111+
- name: Build
112+
run: cargo build --verbose
113+
114+
- name: Test
115+
run: cargo test --verbose
116+
117+
- name: Install coverage tooling
118+
run: rustup component add llvm-tools-preview
119+
120+
- name: Build instrumented binaries for E2E coverage
121+
run: |
122+
RUSTFLAGS='-C instrument-coverage' \
123+
cargo build --all-features --workspace --bins --examples
124+
125+
- name: Run coverage tests
126+
run: |
127+
mkdir -p target/coverage
128+
RUSTFLAGS='-C instrument-coverage' \
129+
LLVM_PROFILE_FILE='target/coverage/ptools-%p-%m.profraw' \
130+
cargo test --all-features --workspace --tests --bins
131+
132+
- name: Report coverage
133+
shell: bash
134+
run: |
135+
target_dir="target/i686-unknown-linux-gnu/debug"
136+
host_target=$(rustc -vV | awk '/host:/ {print $2}')
137+
llvm_bin="$(rustc --print sysroot)/lib/rustlib/${host_target}/bin"
138+
"${llvm_bin}/llvm-profdata" merge -sparse target/coverage/*.profraw -o target/coverage/ptools.profdata
139+
"${llvm_bin}/llvm-cov" report \
140+
--ignore-filename-regex='/(\.cargo/registry|rustc)/' \
141+
--instr-profile=target/coverage/ptools.profdata \
142+
"${target_dir}/pargs" --object "${target_dir}/pauxv" --object "${target_dir}/penv" \
143+
--object "${target_dir}/pfiles" --object "${target_dir}/plgrp" --object "${target_dir}/prun" \
144+
--object "${target_dir}/psig" --object "${target_dir}/pstop" --object "${target_dir}/ptree" \
145+
--object "${target_dir}/pwait"

examples/pargs_penv.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@ fn apply_test_overrides_from_env() {
88
let hard = env::var("PTOOLS_TEST_SET_RLIMIT_NOFILE_HARD").ok();
99
match (soft, hard) {
1010
(Some(soft), Some(hard)) => {
11-
let soft = soft.parse::<u64>().expect("invalid NOFILE soft override");
12-
let hard = hard.parse::<u64>().expect("invalid NOFILE hard override");
11+
let soft = soft
12+
.parse::<nix::libc::rlim_t>()
13+
.expect("invalid NOFILE soft override");
14+
let hard = hard
15+
.parse::<nix::libc::rlim_t>()
16+
.expect("invalid NOFILE hard override");
1317
let lim = nix::libc::rlimit {
1418
rlim_cur: soft,
1519
rlim_max: hard,

src/bin/pfiles.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,6 @@ fn print_open_flags(flags: u64) {
223223
(OFlag::O_DIRECTORY, "O_DIRECTORY"),
224224
(OFlag::O_DSYNC, "O_DSYNC"),
225225
(OFlag::O_EXCL, "O_EXCL"),
226-
(OFlag::O_LARGEFILE, "O_LARGEFILE"),
227226
(OFlag::O_NOATIME, "O_NOATIME"),
228227
(OFlag::O_NOCTTY, "O_NOCTTY"),
229228
(OFlag::O_NOFOLLOW, "O_NOFOLLOW"),
@@ -1103,6 +1102,7 @@ fn print_fd_details(source: &dyn ProcSource, fd: u64, path: &Path) {
11031102
}
11041103
}
11051104

1105+
#[allow(clippy::unnecessary_cast)]
11061106
fn print_file(
11071107
source: &dyn ProcSource,
11081108
fd: u64,
@@ -1153,8 +1153,8 @@ fn print_file(
11531153
FileType::Posix(PosixFileType::Socket) => {
11541154
// Socket metadata is resolved from /proc/<pid>/net/*, so inode lookups are
11551155
// evaluated in the target process's network namespace.
1156-
if let Some(sock_info) = sockets.get(&stat_info.st_ino) {
1157-
debug_assert_eq!(sock_info.inode, stat_info.st_ino);
1156+
if let Some(sock_info) = sockets.get(&(stat_info.st_ino as u64)) {
1157+
debug_assert_eq!(sock_info.inode, stat_info.st_ino as u64);
11581158
// pidfd_open / pidfd_getfd for fd duplication -- live-only.
11591159
let sock_fd = duplicate_target_fd(pid, fd);
11601160
print_sockname(sock_info);

src/lib.rs

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -176,34 +176,35 @@ pub fn print_env(pid: u64) -> bool {
176176
const AT_RSEQ_FEATURE_SIZE: u64 = 27;
177177
const AT_RSEQ_ALIGN: u64 = 28;
178178

179+
#[allow(clippy::unnecessary_cast)]
179180
const AUX_NAMES: &[(u64, &str)] = &[
180-
(libc::AT_BASE, "AT_BASE"),
181-
(libc::AT_BASE_PLATFORM, "AT_BASE_PLATFORM"),
182-
(libc::AT_CLKTCK, "AT_CLKTCK"),
183-
(libc::AT_EGID, "AT_EGID"),
184-
(libc::AT_ENTRY, "AT_ENTRY"),
185-
(libc::AT_EUID, "AT_EUID"),
186-
(libc::AT_EXECFD, "AT_EXECFD"),
187-
(libc::AT_EXECFN, "AT_EXECFN"),
188-
(libc::AT_FLAGS, "AT_FLAGS"),
189-
(libc::AT_GID, "AT_GID"),
190-
(libc::AT_HWCAP2, "AT_HWCAP2"),
191-
(libc::AT_HWCAP, "AT_HWCAP"),
192-
(libc::AT_IGNORE, "AT_IGNORE"),
193-
(libc::AT_MINSIGSTKSZ, "AT_MINSIGSTKSZ"),
194-
(libc::AT_NOTELF, "AT_NOTELF"),
195-
(libc::AT_NULL, "AT_NULL"),
196-
(libc::AT_PAGESZ, "AT_PAGESZ"),
197-
(libc::AT_PHDR, "AT_PHDR"),
198-
(libc::AT_PHENT, "AT_PHENT"),
199-
(libc::AT_PHNUM, "AT_PHNUM"),
200-
(libc::AT_PLATFORM, "AT_PLATFORM"),
201-
(libc::AT_RANDOM, "AT_RANDOM"),
181+
(libc::AT_BASE as u64, "AT_BASE"),
182+
(libc::AT_BASE_PLATFORM as u64, "AT_BASE_PLATFORM"),
183+
(libc::AT_CLKTCK as u64, "AT_CLKTCK"),
184+
(libc::AT_EGID as u64, "AT_EGID"),
185+
(libc::AT_ENTRY as u64, "AT_ENTRY"),
186+
(libc::AT_EUID as u64, "AT_EUID"),
187+
(libc::AT_EXECFD as u64, "AT_EXECFD"),
188+
(libc::AT_EXECFN as u64, "AT_EXECFN"),
189+
(libc::AT_FLAGS as u64, "AT_FLAGS"),
190+
(libc::AT_GID as u64, "AT_GID"),
191+
(libc::AT_HWCAP2 as u64, "AT_HWCAP2"),
192+
(libc::AT_HWCAP as u64, "AT_HWCAP"),
193+
(libc::AT_IGNORE as u64, "AT_IGNORE"),
194+
(libc::AT_MINSIGSTKSZ as u64, "AT_MINSIGSTKSZ"),
195+
(libc::AT_NOTELF as u64, "AT_NOTELF"),
196+
(libc::AT_NULL as u64, "AT_NULL"),
197+
(libc::AT_PAGESZ as u64, "AT_PAGESZ"),
198+
(libc::AT_PHDR as u64, "AT_PHDR"),
199+
(libc::AT_PHENT as u64, "AT_PHENT"),
200+
(libc::AT_PHNUM as u64, "AT_PHNUM"),
201+
(libc::AT_PLATFORM as u64, "AT_PLATFORM"),
202+
(libc::AT_RANDOM as u64, "AT_RANDOM"),
202203
(AT_RSEQ_FEATURE_SIZE, "AT_RSEQ_FEATURE_SIZE"),
203204
(AT_RSEQ_ALIGN, "AT_RSEQ_ALIGN"),
204-
(libc::AT_SECURE, "AT_SECURE"),
205-
(libc::AT_SYSINFO_EHDR, "AT_SYSINFO_EHDR"),
206-
(libc::AT_UID, "AT_UID"),
205+
(libc::AT_SECURE as u64, "AT_SECURE"),
206+
(libc::AT_SYSINFO_EHDR as u64, "AT_SYSINFO_EHDR"),
207+
(libc::AT_UID as u64, "AT_UID"),
207208
];
208209

209210
fn aux_key_name(key: u64) -> String {
@@ -319,6 +320,7 @@ fn read_auxv_from(source: &dyn ProcSource) -> Option<Vec<(u64, u64)>> {
319320
}
320321

321322
#[cfg(target_arch = "x86_64")]
323+
#[allow(clippy::unnecessary_cast)]
322324
fn decode_hwcap(key: u64, value: u64) -> Option<String> {
323325
// AT_HWCAP on x86_64: CPUID leaf 1 EDX register bits
324326
const HWCAP_NAMES: &[(u32, &str)] = &[
@@ -356,9 +358,9 @@ fn decode_hwcap(key: u64, value: u64) -> Option<String> {
356358
// AT_HWCAP2 on x86_64: kernel-defined bits from asm/hwcap2.h
357359
const HWCAP2_NAMES: &[(u32, &str)] = &[(0, "RING3MWAIT"), (1, "FSGSBASE")];
358360

359-
let table = if key == libc::AT_HWCAP {
361+
let table = if key == libc::AT_HWCAP as u64 {
360362
HWCAP_NAMES
361-
} else if key == libc::AT_HWCAP2 {
363+
} else if key == libc::AT_HWCAP2 as u64 {
362364
HWCAP2_NAMES
363365
} else {
364366
return None;
@@ -378,6 +380,7 @@ fn decode_hwcap(key: u64, value: u64) -> Option<String> {
378380
}
379381

380382
#[cfg(target_arch = "aarch64")]
383+
#[allow(clippy::unnecessary_cast)]
381384
fn decode_hwcap(key: u64, value: u64) -> Option<String> {
382385
// AT_HWCAP on aarch64: bits from arch/arm64/include/uapi/asm/hwcap.h
383386
const HWCAP_NAMES: &[(u32, &str)] = &[
@@ -464,9 +467,9 @@ fn decode_hwcap(key: u64, value: u64) -> Option<String> {
464467
(44, "HBC"),
465468
];
466469

467-
let table = if key == libc::AT_HWCAP {
470+
let table = if key == libc::AT_HWCAP as u64 {
468471
HWCAP_NAMES
469-
} else if key == libc::AT_HWCAP2 {
472+
} else if key == libc::AT_HWCAP2 as u64 {
470473
HWCAP2_NAMES
471474
} else {
472475
return None;
@@ -490,12 +493,14 @@ fn decode_hwcap(_key: u64, _value: u64) -> Option<String> {
490493
None
491494
}
492495

496+
#[allow(clippy::unnecessary_cast)]
493497
fn is_uid_auxv_key(key: u64) -> bool {
494-
key == libc::AT_UID || key == libc::AT_EUID
498+
key == libc::AT_UID as u64 || key == libc::AT_EUID as u64
495499
}
496500

501+
#[allow(clippy::unnecessary_cast)]
497502
fn is_gid_auxv_key(key: u64) -> bool {
498-
key == libc::AT_GID || key == libc::AT_EGID
503+
key == libc::AT_GID as u64 || key == libc::AT_EGID as u64
499504
}
500505

501506
pub fn resolve_uid(uid: u32) -> Option<String> {
@@ -520,11 +525,12 @@ pub fn resolve_gid(gid: u32) -> Option<String> {
520525
name.to_str().ok().map(str::to_string)
521526
}
522527

528+
#[allow(clippy::unnecessary_cast)]
523529
pub fn print_auxv_from(source: &dyn ProcSource) -> bool {
524530
if let Some(auxv) = read_auxv_from(source) {
525531
print_proc_summary_from(source);
526532
for (key, value) in auxv {
527-
if key == libc::AT_EXECFN {
533+
if key == libc::AT_EXECFN as u64 {
528534
let s = source
529535
.read_exe()
530536
.ok()

0 commit comments

Comments
 (0)