6,486 karma · joined July 15, 2018
blog: tanelpoder.com
$ ln -s /bin/sleep '[kernelstuff]'
$ ./\[kernelstuff\] 999 &
[2] 29499
$ awk '{ printf("%x\n", $9) }' /proc/29499/stat
40400000
$ pgrep kthreadd
2
$ awk '{ printf("%x\n", $9) }' /proc/2/stat
208040
Edit: as you said, it's superficial disguising (that may even work in some cases)Edit: this answer has some relevant details:
https://stackoverflow.com/questions/63713056/why-is-their-a-...
The internal syscall numbers are defined in syscall_64.tbl in kernel source and you can parse the (libc-used) syscall numbers from various /usr/include/asm/syscall.h files, but these files don't necessarily contain all the available syscalls in your currently running kernel.
You can read your kernel's/platform's currently available syscalls from the relevant /sys/kernel/debug/tracing tracepoint files (I posted a link to my script in another comment here). That way you'll see all currently available system calls and their arguments, but tracefs doesn't show the syscall internal numbers (syscall table slot numbers), but rather the new syscall ID.
The internal syscall numbering can change when you switch/build a new kernel and syscalls have different numbers across platforms. Syscall 0 is "read" on x86_64, but is "io_setup" on aarch64, for example. The new syscall ID aims to provide stable numbering with no conflicts and overlaps across platforms and kernel versions, as I understand.
I recently had enough of parsing the various syscall.h files on different architectures and wrote a debugfs syscall info reader instead. That way you can see all tracepoint-instrumented syscalls and arguments available exactly on your currently running kernel on your platform:
https://tanelpoder.com/posts/list-linux-system-call-argument...
Edit: changed "all" to "all tracepoint-instrumented" based on a comment below - some added syscalls don't (immediately) get instrumented with a tracepoint so tracefs wouldn't show them (until someone instruments them in a later kernel version as seems to be the case). The tracefs approach has been good enough for me, but the only 100% guaranteed way to see all currently available syscalls would be to read the syscall table from kernel memory and see which syscall handler kernel functions they call (as the syscall name itself is meaningless inside the kernel).
$ sudo wc -l /sys/kernel/debug/kprobes/blacklist
783 /sys/kernel/debug/kprobes/blacklist
Edit: Perhaps an alternative approach would be to attach probes to relevant (precise) PMU events. There's also this prototype of adding breakpoint/watchpoint support to eBPF [1]. But actually doing stuff within this context may get complicated very fast, so would need to be severely limited, if feasible at all.[1] https://ebpf.io/summit-2020-slides/eBPF_Summit_2020-Lightnin...
There are also plenty of multitenant apps out there that have the same set of tables (with their own data) duplicated across all schemas.
Also, the launch happens fast - if you plan to record it with your phone, set it up on a tripod or something before and not muck with it at all, you’ll miss the first seconds of the launch fast and by then the rocket is already pretty far up.
Execname is a variable in DTrace and not a probe (?), so how would it help with automatically attaching to new PIDs? Now that I recall more details, there was no issue with statically defined kernel "fbt" probes nor "profile", but the userspace pid one was where I hit this limitation.
Back when I tried to build xcapture with DTrace, I could launch the script and use something like /pid$oracle::func:entry/ but IIRC the probe was attached only to the processes that already existed and not any new ones that were started after loading the DTrace probes. Maybe I should have used some lower level APIs or something - but eBPF on Linux automatically handles both existing and new processes.
I did like the brief period of working (or just browsing stuff) while lying on the couch, but I knew from the beginning that I didn't need an even lazier position for staring at a screen all day.
What I loved about DTrace was that once it was out, even in beta, it was pretty complete and worked - all the DTrace ports that I've tried, including on Windows (!) a few years ago were very limited or had some showstopper issues. I guess eBPF was like that too some years ago, but by now it's pretty sweet even for more regular consumer who don't keep track of its development.
Edit: Oh, wasn't aware of the timeline, I may have some dates (years) wrong in my memory
But libbpf with CO-RE will solve these issues as I understand, so as long as the kernel supports what you need, the CO-RE binary will work.
This raises another issue for me though, it's not easy, but easier, for enterprises to download and run a single python + single C source file (with <500 code lines to review) than a compiled CO-RE binary, but my long term plan/hope is that I (we) get the RedHats and AWSes of this world to just provide the eventual mature release as a standard package.
But the sched_switch tracepoint is the hottest event, without stack sampling it's 200-500ns per event (on my Xeon 63xx CPUs), depending on what data is collected. I use #ifdefs to compile in only the fields that are actually used (smaller thread_state struct, fewer branches and instructions to decode & cache). Surprisingly when I collect kernel stack, the overhead jumps higher up compared to user stack (kstack goes from say 400ns to 3200ns, while ustack jumps to 2800ns per event or so).
I have done almost zero optimizations (and I figure using libbpf/BTF/CO-RE will help too). But I'm ok with these numbers for most of my workloads of interest, and since eBPF programs are not cast in stone, can do further reductions, like actually sampling stacks in the sched_switch probe on every 10th occurrence or something.
So in worst case, this full-visibility approach might not be usable as always-on instrumentation for some workloads (like some redis/memcached/mysql lookups doing 10M context switches/s on a big server), but even with such workloads, a temporary increase in instrumentation overhead might be ok, when there are known recurring problems to troubleshoot.
- https://blogs.oracle.com/linux/post/bpftune-using-reinforcem...
Perf+flamegraphs were able to catch in-interrupt-handling samples as I was on a bare metal machine with PMU counters accessible. But the various NVMe I/O completion interrupts happened all over the place, even when the CPUs were in random userspace code sections. Neither the bottom-up & top-down FlameGraph approach made it visually clear in this case.
But since interrupt time did show up and since the FlameGraph JS tool had a text search box, I searched for "interrupt" or "irq" in the search box - and the JS code highlighted all matching sections with purple color (completely distinct from the classic color range of flamegraphs). And seeing that purple color all over the place made me smile and gave me a strong visual "a-ha" moment. Probably with some extra JS tinkering, these kinds of "events scattered all over the place" scenarios could be made even clearer.
$ cd ~/bin
$ for x in $(find . -type f -perm /a=x -exec basename {} \;) ; do echo $x ; done
temps
$ for x in $(find . -type f -perm /a=x -exec basename {} \;) ; do ln -s $x ,$x ; done
$ ls -l
total 4
lrwxrwxrwx 1 tanel tanel 5 Jun 23 16:38 ,temps -> temps
-rwxr--r-- 1 tanel tanel 251 May 30 23:26 tempsEdit: other comments below explain the missing part, in a regular drive, apparently just one head can read/write (to one platter) at a time due to calibration reasons, even if your disk physically has 8 platters. So having two actuators allows two platters out of 8 to do IO concurrently.