> Which goes to show that Ctrl-C profiling is often enough to solve a simple problem, and it’s usually much easier than learning how to use a profiler and how to properly read its output
As the article says, this is a low frequency sampling profiler, which means it comes with all the caveats of a sampling profiler, and interpreting its output. As a very crude tool, sure, but it is not an excuse to not learnt to use a profiler. Perf, instruments and UIForETW are simple enough to use that anyone who can follow the instructions in this blog past can pick up the basics in the same length of time.
Sure, it's a fine technique if essentially one thing is consuming all the CPU time (and it shouldn't), which does happen. It becomes tedious when you're looking for the thing that consumes 20% or so of the CPU time.
Once upon a time (maybe even before pthreads) I made an automatic version of this using SIGALARM for profiling.
I made a wrapper (using LD_PRELOAD) around XSelectInput that would trigger the signal 0.1 seconds after a keyboard/mouse (or other event) was received... Then it would dump stack traces every 0.1 seconds where "slow" UI code was being executed (before next call to XSelectInput).
Ages ago, working on an embedded system we did something similar by running gdb server on the embedded machine and gdb on the server and running a script to collect periodic stack traces to get a sampling profiler.
I kind of do a variant of this sometimes with “pause” in the Xcode debugger. If I’ve just encountered some kind of hang or delay, often hitting that will put me in the right place in the threads/call stack to figure out what I did.
Wrap gdb in a shell script and you’ve got yourself an actual profiler: https://poormansprofiler.org/
The first footnote here had me cackling aloud. Don't miss the footnotes!
This is interestingly analogous to nelhage's memory sampling approach https://blog.nelhage.com/2013/03/tracking-an-eventmachine-le... where if something is leaking "at scale", let it - then gcore it, and pick a random page of the core and see what's there. (An even cheaper variant I've used a few times with python is to just run "strings | sort | uniq -c | sort -n" on the core, so you get the most common strings which are usually part of object metadata and give you a solid hint without needing to go in with a debugger...) The ^C approach basically samples time instead of memory.