今日已更新 116 条资讯 | 累计 29258 条内容
关于我们

ratatop: the process table, and the parentheses that ruin everything

Athreya aka Maneshwar 2026年08月08日 02:21 0 次阅读 来源:Dev.to

Hello, I'm Maneshwar. I'm building git-lrc, a Micro AI code reviewer that runs on every commit. It is free and source-available on Github. Star git-lrc to help devs discover the project. Do give it a try and share your feedback. CPU, memory, disks and network were all "read a file, do some arithmetic, draw it". This one is different. It reads about 400 directories every tick, and it is the first box you can actually interact with. There is one bug in here that I would bet real money most /proc parsers have shipped at some point. Let me start there. The parentheses that ruin everything Here is a line from /proc/[pid]/stat : 125045 (cat) R 125025 125045 125025 0 -1 4194304 92 0 0 0 11 22 0 0 20 0 7 0 ... Space separated. Field 1 is the pid, field 2 is the process name in parentheses, field 14 is user time, field 15 is system time, field 20 is thread count, field 24 is resident memory. So you split on whitespace and index into the result. Obvious. Works perfectly. Until someone runs a process called my (weird) app . 42 (my (weird) app) S 1 42 1 0 -1 0 0 0 0 0 5 5 0 0 20 0 3 0 ... That name is three whitespace-separated tokens, so every field after it shifts by two. Your thread count is now reading someone's page fault counter. Your memory is reading a scheduling priority. Nothing crashes. The numbers are just quietly, confidently wrong. And the process name is fully user-controlled. Anyone can rename a thread to whatever they like. The fix is to not split the whole line at all. Find the last closing parenthesis, take the name from between the first ( and that, and only then split what remains: fn parse_stat ( raw : & str ) -> Option < Stat > { let open = raw .find ( '(' ) ? ; let close = raw .rfind ( ')' ) ? ; let name = raw .get ( open + 1 .. close ) ? .to_string (); // Fields resume at `state`, which is field 3 in the man page's numbering. let fields : Vec <& str > = raw .get ( close + 1 .. ) ? .split_whitespace () .collect (); let field = | number : usize | -> u64 {

本文内容来源于互联网,版权归原作者所有
查看原文