Remix.run Logo
Pawamoy 7 days ago

I'll get a closer look at the code tomorrow, but maybe you can provide an answer in the meantime: how do you handle line numbers? Bash's LINENO is unreliable, contrary to Zsh's, see https://gist.github.com/pawamoy/cca35f0f5ccd56665d6421e9b2d2.... That's why I eventually gave up writing any profiling/tracing/debugging/coverage tool for Bash and moved to support these in Zsh instead. Unfortunately Zsh is missing a ZSH_XTRACEFD like Bash, but that's another story (never finished contributing one). Here's my own attempt at a shell profiler: https://github.com/shellm-org/profiler :)

jkool702 7 days ago | parent [-]

the LINENO is (mostly) reliable, so long as the code that is running comes from a file somewhere. timep runs the code that you want profiled by generating a script file that:

1. declares all the variables timep uses to track state and things like that 2. initializes all the extra stuff needed to make the instrumentation work (initial values for some variables, defining instrumented traps, setting `set -T`, etc.) 3. runs the code to be profiled. for scripts the script content is added here. For raw commands the commands are added. For functions the function is defined and then called as a function.

this is saved as a script in the timep tmpdir (by default a unique directory under /dev/shm/.timep), made executable, and then it is run. The setup is done like this for a few reasons, but the biggest of those is "to get correct LINENOs.

This makes it so that LINENO gives a correct result, only it is shifted by however many lines it takes to do steps 1 and 2.so the code records the lineno just before the "code to be profiled" starts running, so it can shift it back the right amount when it records it.

That said, timep has a handful of very minor bugs (4 to be precise) - one of them is that fir functions that call a subshell the lineno is wrong (it is shifted forward by a few hundred lines). So it isnt quite 100% perfect, but is pretty close.

(side note: the other 3 bugs have to do with command grouping in the output being ever so slightly off for deeply nested subshell + background fork sequences).

timep also includes a function that I wrote that tries to get the original function code (instead of the version that `declare -f` outputs), so that the lineno's on functions match up better with the original function definition source code.