-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
execution traces (eg for code coverage, debugging, introspection, profiling) #15827
Conversation
My idea is to upgrade existing https://nim-lang.github.io/Nim/manual_experimental.html#term-rewriting-macros functionality to make things like coverage, extra debug reports possible. Effectively term rewriting macro should be able to find and rewrite any proc, if statement, case statement, for loop and etc. Up for discussion. |
a05a0cf
to
1d036ab
Compare
@cooldome TRW are IMO the wrong approach for this, because they're not flexible enough: they're trying to cram everything into a succinct DSL, which has the big downside of being cryptic and too limiting, including for this task. There are other downsides too (also due to their inflexibilty because of its limiting DSL), eg the fact that it recursively applies unconditionally. That said, in the meantime the feature implemented in this PR is IMO very useful for a variety of use cases so it's justified on its own. If/when something like whole-program AST transformation (like timotheecour#75) is implemented, we can always revisit the implementation of |
1d036ab
to
4d42f48
Compare
Where is the RFC? |
I can make one once I'm satisfied with the API and add missing functionality. But this is already usable (modulo commits I haven't pushed yet) |
The forum post updated(https://forum.nim-lang.org/t/7024)
|
Ya i saw that,
likewise with tools like gcov, see binhonglee/coco#13 and other issues When it comes to debugging, you often need more than 1 tool to get the job done, it's not an either/or. And yes, I do intend to revive this PR. |
I can register events, but haven't figured out how to get compiled function names (suggestions from https://stackoverflow.com/questions/11731229/dladdr-doesnt-return-the-function-name) dont work at all. Maybe this is fixable, though I would much rather prefer to use nim-lang/Nim#15827 anyway.
- https://hookrace.net/blog/nim-code-coverage/ is outdated, `--nimcache:.` is also needed, because `.gcda` files are generated (at least in my case), where binary was compiled, not where it was executed. At least passing this flag solved the issue - Also need to `--remove "<temporary test dir>/*'` from code coverage, idk why. - As expected cove coverage report is awful, makes almost no sense. - Another example why we need adequate code coverage that is aware of the nim semantics. nim-lang/Nim#15827 - `exec` is horrible, nim-lang/nimble#895 is needed. I wanted to break arguments into something more manageable, and ended up with `&"\"{dir}/*\""`. Super nice.
Just want to share my experience trying other "alternative" options for code coverage and profiling, maybe this will be taken in account in later pros/cons discussion (that of course will happen).
|
So, to summarize this relatively long list - absolutely all options I've tried are horrible, ill-suited for anything, including C itself, based on ad-hoc formats, require hacking around just to get something meaningful while still providing abysmal output. |
thanks, this is useful.
I kind of doubt it because they'd need to understand how nim does exception handling in particular (eg with jmp etc depending on which gc is used), but I'd be curious. this PR can (pending pushing latest commits), and has relatively low overhead (~2x), ~10 nanosecond precision (thanks to #18743 via |
Although I'm personally not that interested in performance metrics, so I didn't investigate it really deeply (just get an overall picture of what is going on in my code). What I'm really interested in is a code coverage and especially! execution traces, as they, in my opinion, provide the ability to get insights into code execution in a way that no other tool could. Debugging, behavior detection (user can detect changes in control flow (if there is any) by simply running the program under two library (dependency) versions) and just general understanding of the code (for example, I could run |
Getting a little ahead, but - current API does not provide access to the information where proc has been called, correct?
where TFrame {...} = object
prev*: PFrame ## Previous frame; used for chaining the call stack.
procname*: cstring ## Name of the proc that is currently executing. [3]
line*: int ## Line number of the proc that is currently executing.
filename*: cstring ## Filename of the proc that is currently executing.
len*: int16 ## Length of the inspectable slots.
calldepth*: int16 ## Used for max call depth checking.
when NimStackTraceMsgs:
frameMsgLen*: int ## end position in frameMsgBuf for this frame. [1] what about [2] If column information was also taken into account, it would probably be enough to retrieve "who called" information using secondary code processing. [3] proc main(a: int) =
for e in getStackTraceEntries():
echo e
proc main(b: string) = main(1)
proc main(q: char) = main("srrt")
proc main() = main('1')
main()
[4] If we assume there is always one node per |
This pull request has been automatically marked as stale because it has not had recent activity. If you think it is still a valid PR, please rebase it on the latest devel; otherwise it will be closed. Thank you for your contributions. |
links