Skip to content
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

Track function start and end #2782

Merged
merged 1 commit into from Aug 15, 2019
Merged

Track function start and end #2782

merged 1 commit into from Aug 15, 2019

Conversation

grahamc
Copy link
Member

@grahamc grahamc commented Apr 24, 2019

Track function start and ends for flame graphs

With this patch, and this file I called log.py:

#!/usr/bin/env nix-shell
#!nix-shell -i python3 -p python3 --pure

import sys
from pprint import pprint

stack = []
timestack = []

for line in open(sys.argv[1]):
    components = line.strip().split(" ", 2)
    if components[0] != "function-trace":
        continue

    direction = components[1]
    components = components[2].rsplit(" ", 2)

    loc = components[0]
    _at = components[1]
    time = int(components[2])

    if direction == "entered":
        stack.append(loc)
        timestack.append(time)
    elif direction == "exited":
        dur = time - timestack.pop()
        vst = ";".join(stack)
        print(f"{vst} {dur}")
        stack.pop()

and:

nix-instantiate -vvvvvvv ../nixpkgs/pkgs/top-level/release.nix -A unstable > log.matthewbauer 2>&1
./log.py ./log.matthewbauer > log.matthewbauer.folded
flamegraph.pl --title matthewbauer-post-pr log.matthewbauer.folded > log.matthewbauer.folded.svg

I can make flame graphs like: http://gsc.io/log.matthewbauer.folded.svg

@edolstra
Copy link
Member

Isn't this potentially very expensive since it may do a syscall on the hot path? (I think on Linux the current time is obtained from the vDSO, but on other platforms it might require an actual syscall.)

src/libexpr/eval.cc Outdated Show resolved Hide resolved
@grahamc grahamc force-pushed the flames branch 2 times, most recently from cf84cf7 to 4910bad Compare April 24, 2019 12:03
@grahamc
Copy link
Member Author

grahamc commented Apr 24, 2019

I updated it to be conditional on debug logs, changed the log.py to accept a parameter, and replaced :fire: with function-trace.

src/libexpr/eval.cc Outdated Show resolved Hide resolved
src/libexpr/eval.cc Outdated Show resolved Hide resolved
With this patch, and this file I called `log.py`:

    #!/usr/bin/env nix-shell
    #!nix-shell -i python3 -p python3 --pure

    import sys
    from pprint import pprint

    stack = []
    timestack = []

    for line in open(sys.argv[1]):
        components = line.strip().split(" ", 2)
        if components[0] != "function-trace":
            continue

        direction = components[1]
        components = components[2].rsplit(" ", 2)

        loc = components[0]
        _at = components[1]
        time = int(components[2])

        if direction == "entered":
            stack.append(loc)
            timestack.append(time)
        elif direction == "exited":
            dur = time - timestack.pop()
            vst = ";".join(stack)
            print(f"{vst} {dur}")
            stack.pop()

and:

    nix-instantiate --trace-function-calls -vvvv ../nixpkgs/pkgs/top-level/release.nix -A unstable > log.matthewbauer 2>&1
    ./log.py ./log.matthewbauer > log.matthewbauer.folded
    flamegraph.pl --title matthewbauer-post-pr log.matthewbauer.folded > log.matthewbauer.folded.svg

I can make flame graphs like: http://gsc.io/log.matthewbauer.folded.svg

---

Includes test cases around function call failures and tryEval. Uses
RAII so the finish is always called at the end of the function.
@grahamc
Copy link
Member Author

grahamc commented Aug 14, 2019

I've updated this PR to use the option like you suggested, and also switched to RAII for the trace. I also added the stack collapse script in to ./contrib. I haven't checked how it impacts performance when the option is disabled.

@grahamc
Copy link
Member Author

grahamc commented Aug 14, 2019

I'm testing this PR against some particularly complex Nix expressions which the original implementation did not properly trace.

@grahamc
Copy link
Member Author

grahamc commented Aug 14, 2019

Yep. It worked great on those test cases. I think this is good to go!

@edolstra edolstra merged commit 477f82e into NixOS:master Aug 15, 2019
@hamishmack
Copy link

hamishmack commented Dec 5, 2019

The option to use is now --trace-function-calls not -vvvvvvv

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants