# ANN: TraceCalls.jl, a debugging and profiling tool for Julia 0.6

**URL:** https://discourse.julialang.org/t/ann-tracecalls-jl-a-debugging-and-profiling-tool-for-julia-0-6/5283
**Category:** Community
**Tags:** package, announcement
**Created:** [August 8, 2017, 4:06pm UTC](https://discourse.julialang.org/t/ann-tracecalls-jl-a-debugging-and-profiling-tool-for-julia-0-6/5283 "2017-08-08T16:06:19Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)
#### Post date: [August 8, 2017, 4:06pm UTC](https://discourse.julialang.org/t/ann-tracecalls-jl-a-debugging-and-profiling-tool-for-julia-0-6/5283/1 "2017-08-08T16:06:19Z")

</div>

I’m proud to announce [TraceCalls.jl](http://nbviewer.jupyter.org/github/cstjean/TraceCalls.jl/blob/master/README.ipynb), a functional tracing package with support for [IJulia](https://github.com/JuliaLang/IJulia.jl), [Atom](http://junolab.org/) and the REPL.

 ![35](https://global.discourse-cdn.com/julialang/original/3X/a/9/a9fe0b50f4b714a027614a00bb202d11c2360a97.png)

Like traditional tracing packages, TraceCalls.jl displays a tree function calls. It goes further by returning a fully-[explorable](http://nbviewer.jupyter.org/github/cstjean/TraceCalls.jl/blob/master/README.ipynb#Manipulating-traces) tree-like data structure. This enables some interesting workflows, such as [debugging](http://nbviewer.jupyter.org/github/cstjean/TraceCalls.jl/blob/master/README.ipynb#Debugging-with-traces) by [highlighting the differences between two code versions](http://nbviewer.jupyter.org/github/cstjean/TraceCalls.jl/blob/master/README.ipynb#Debugging-test-failures)

 ![32](https://global.discourse-cdn.com/julialang/original/3X/6/8/684dfd7c1d2824d5ad23f7edf54596b552508eda.png)

[Profiling](http://nbviewer.jupyter.org/github/cstjean/TraceCalls.jl/blob/master/README.ipynb#Profiling)

 ![06](https://global.discourse-cdn.com/julialang/original/3X/2/e/2e1d4b1a0952e14f20b0a1e8bdd59b0229c6300a.png)

Or [tracking down type instability](http://nbviewer.jupyter.org/github/cstjean/TraceCalls.jl/blob/master/README.ipynb#Profiling)

 ![16](https://global.discourse-cdn.com/julialang/original/3X/1/a/1a9ee0bdd34b8547271e9b80baef462db84d2177.png)

[Check it out](http://nbviewer.jupyter.org/github/cstjean/TraceCalls.jl/blob/master/README.ipynb) and let me know what you think! The current release has been tested on most major packages, but it is still a bit beta, with a few [known limitations](http://nbviewer.jupyter.org/github/cstjean/TraceCalls.jl/blob/master/README.ipynb#Syntax). It’s also relatively slow to trace large modules. The next version will improve on that.

Best,

Cédric

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [August 9, 2017, 8:33am UTC](https://discourse.julialang.org/t/ann-tracecalls-jl-a-debugging-and-profiling-tool-for-julia-0-6/5283/2 "2017-08-09T08:33:49Z")

</div>

Looks awesome! A neat feature to implement on top of this would be auto-generatrion of unit tests. Basically re-formatting the output to something like:

```julia
@testset "@trace proportions([1,2,2,2,3])" begin
  @test proportions([1,2,2,2,3]) ≈ [0.2, 0.6, 0.2]
    @test span([1,2,2,2,3]) == 1:3 
  ...
end

```

Optionally, the auto-generated test set could be stored directly in a `.jl` file (with an associated `.h5` file for larger objects) and an `include` line added to the `runtests.jl` file of the relevant package.

(Of course, the point of this is not to verify that the code does what it already does, but rather to hunt down bugs by generating tests that trigger them.)

---

<div class="post-metadata">

### Author: ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)
#### Post date: [August 9, 2017, 3:16pm UTC](https://discourse.julialang.org/t/ann-tracecalls-jl-a-debugging-and-profiling-tool-for-julia-0-6/5283/3 "2017-08-09T15:16:59Z")

</div>

You could do something like:

```julia
> trace_prop = @trace StatsBase proportions([1,2,2,2,3])
> 
> for trace in collect(trace_prop)[2:end] # exclude the root
> io = STDOUT; mime=MIME"text/plain"()
> print(io, "@test ")
> TraceCalls.show_func_name(io, mime, trace)
> write(io, "(")
> TraceCalls.show_args(io, mime, trace.args)
> TraceCalls.show_kwargs(io, mime, trace.kwargs)
> println(io, ") == $(trace.value)")
> end

@test StatsBase.proportions([1, 2, 2, 2, 3]) == [0.2, 0.6, 0.2]
@test StatsBase.span([1, 2, 2, 2, 3]) == 1:3
@test StatsBase.proportions([1, 2, 2, 2, 3], 1:3) == [0.2, 0.6, 0.2]
@test StatsBase.counts([1, 2, 2, 2, 3], 1:3) == [1, 3, 1]
@test StatsBase.addcounts!([1, 3, 1], [1, 2, 2, 2, 3], 1:3) == [1, 3, 1]

```

It works for simple functional code, but it’ll be tricky to deal with closures, and [mutable state](http://nbviewer.jupyter.org/github/cstjean/TraceCalls.jl/blob/master/README.ipynb#Working-with-mutable-state). Another option would be to save the trace via JLD. That would require a PR to that package to handle function and module references.

> [@Per](#):
>
> (Of course, the point of this is not to verify that the code does what it already does, but rather to hunt down bugs by generating tests that trigger them.)

Give `compare_past_trace` a try! It’s useful to debug regressions.

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [August 10, 2017, 6:23am UTC](https://discourse.julialang.org/t/ann-tracecalls-jl-a-debugging-and-profiling-tool-for-julia-0-6/5283/4 "2017-08-10T06:23:49Z")

</div>

Thanks! This is exactly what [I’ve been looking for.](https://discourse.julialang.org/t/how-do-you-use-debuggers/4580/29)

I think, with `compare_past_trace` and just a few lines of code, I can have a function that takes two git commits and returns a set of tests that will work on one but fail on the other. (I prefer work with `runtest.jl` instead of trying out code at the REPL, so this fits perfectly into my workflow.)

Regarding mutable arguments: It’d be great if there were an option to recursively `copy` everything, always, but using a hash table so that multiple copies of the same object are only stored once. (RAM is cheap these days.)

---

<div class="post-metadata">

### Author: ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)
#### Post date: [August 10, 2017, 1:22pm UTC](https://discourse.julialang.org/t/ann-tracecalls-jl-a-debugging-and-profiling-tool-for-julia-0-6/5283/5 "2017-08-10T13:22:59Z")

</div>

> [@Per](#):
>
> Regarding mutable arguments: It’d be great if there were an option to recursively copy everything, always, but using a hash table so that multiple copies of the same object are only stored once. (RAM is cheap these days.)

I don’t think the hash-table thing could work, but you can try playing with `TraceCalls.store(x) = deepcopy(x)`. You’ll probably have problems with functions.

Come to think of it, `TraceCalls.store(x) = REPR(x)` should work perfectly fine for handling mutable state when building a test set.

To handle closures and other unrepresentable objects, maybe you could try running each test with `eval` right away within the `for trace in collect(...)` loop, and if it fails, don’t write it to the file.

With these changes, that looks like a complete solution for auto-generating tests.

> [@Per](#):
>
> I can have a function that takes two git commits and returns a set of tests that will work on one but fail on the other.

PR welcome! We can add a section on testing.

---

<div class="post-metadata">

### Author: ![krcools](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krcools/32/10212_2.png) [@krcools](https://discourse.julialang.org/u/krcools)
#### Post date: [December 7, 2018, 11:10am UTC](https://discourse.julialang.org/t/ann-tracecalls-jl-a-debugging-and-profiling-tool-for-julia-0-6/5283/6 "2018-12-07T11:10:38Z")

</div>

Are there plans to bring this amazing tool to Julia-1.0?

---

<div class="post-metadata">

### Author: ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)
#### Post date: [December 7, 2018, 4:15pm UTC](https://discourse.julialang.org/t/ann-tracecalls-jl-a-debugging-and-profiling-tool-for-julia-0-6/5283/7 "2018-12-07T16:15:48Z")

</div>

Thank you for the kind words. I’d love to bring it back. I may have some time to work on it after the holidays, but it is really not a trivial problem. Any help is appreciated. @pfitzseb showed a promising proof-of-concept on slack, but I haven’t had the time to look into it.
