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

Add a command line flag to create an rr recording #35494

Merged
merged 1 commit into from
Apr 20, 2020
Merged

Add a command line flag to create an rr recording #35494

merged 1 commit into from
Apr 20, 2020

Conversation

Keno
Copy link
Member

@Keno Keno commented Apr 15, 2020

Recently I've been asking people to send me rr recordings whenever
they encounter bugs, since it really streamlines the bug fixing process
(in particular, it cuts out the whole "get it to reproduce and capture
it in rr" part of the process). However, the process so far is not quite
trivial. You have to get rr from somewhere (in a version that isn't broken
for latest julia), you have to remember to pack it and then you have
to find a place to upload it. I put together a package
(https://github.com/JuliaLang/BugReporting.jl [1]) that takes care of all of these
steps, but the convenience isn't quite 100% yet. That's what this PR is
supposed to address. It adds --bug= command line flag that internally
loads up the BugReporting, but passes through all the command line
options, environment, etc. The idea is that to create a bug report
you just do all the things you usually do, but instead of launching
julia, you launch julia --bug. This should also work if you are
launching Julia from within a script, etc.

Demo: https://asciinema.org/a/JFdoGT2wlxBE7uyzM1ZjwgSA5

[1] Note: Not yet registered, I'm waiting for a few dependency bumps to go through.

@DilumAluthge
Copy link
Member

Presumably this only works on Linux?

@Keno
Copy link
Member Author

Keno commented Apr 15, 2020

Yes, rr only works on Linux. That said, I intend the --bug option to be generic and add other kinds of bug report types in the future (e.g. --bug=asciinema that would create an asciinema recording for you or --bug=github that would gather your Project/Manifest/versioninfo and prepare a github template for you.

@StefanKarpinski
Copy link
Member

How about calling the option --bug-report and maybe using -B instead of -b?

@StefanKarpinski
Copy link
Member

Or better still, no short option.

@Keno
Copy link
Member Author

Keno commented Apr 16, 2020

Or better still, no short option.

That's what I did at first, but currently to pass to julia it needs to have a short option or it gets angry at you ;). I agree, I was lazy, I'll fix it.

@Keno
Copy link
Member Author

Keno commented Apr 16, 2020

How about calling the option --bug-report

So the idea was to style it as --bug=[report] in the help where report could be any of a few report types (currently only rr).

@StefanKarpinski
Copy link
Member

I think —bug-report=rr is much clearer than —bug=rr.

@Keno
Copy link
Member Author

Keno commented Apr 16, 2020

Ok, will change.

@tkf
Copy link
Member

tkf commented Apr 16, 2020

How do you pass options to rr (e.g. --chaos, --num-cores)?

@Keno
Copy link
Member Author

Keno commented Apr 16, 2020

How do you pass options to rr (e.g. --chaos, --num-cores)?

I don't really want to add an option for that to the julia command line, but I think JL_RR_RECORD_ARGS as an env variable would be fine and BugReporting.jl could apply them.

@tkf
Copy link
Member

tkf commented Apr 16, 2020

Sounds good to me. Maybe JULIA_RR_RECORD_ARGS, to be consistent with other environment variables used by julia? It works nicely with versioninfo.

@StefanKarpinski
Copy link
Member

Yes! The consistent prefix is JULIA_.

@Keno
Copy link
Member Author

Keno commented Apr 16, 2020

JuliaLang/BugReporting.jl@79a1b3d

@chriselrod
Copy link
Contributor

How would rr deal with e.g. running a JIT’ed función that uses AVX-512 if the replaying machine doesn’t have AVX-512?

-- staticfloat

I also realized a few days ago that my AVX-512 machine can't run ivybridge/sandybridge code (I can't start Julia with -C sandybridge), due to missing an instruction they have, so there may be a lot of incompatibilities between hardware.

@Keno
Copy link
Member Author

Keno commented Apr 16, 2020

You'd need to change the feature set of your CPU at runtime to match the lowest common denominator of what you want to record/replay on. Luckily for the moment, we have some very new machines that have all the features. It does need a kernel patch to work though. For more information, see:

https://lkml.org/lkml/2018/6/16/134
and
https://lkml.org/lkml/2020/4/6/1161

@staticfloat
Copy link
Member

Should we auto-install the BugReporting package if it doesn't exist in the user's global environment? We could even have it auto-add the package to an temporary environment. This way, the default behavior (if BugReporting is not explicitly installed) is to always use the latest stable version of BugReporting (since it would be added to an empty environment every time) and with the gc limits in place, if people are using it often, it wouldn't even be downloaded multiple times either.

@Keno
Copy link
Member Author

Keno commented Apr 16, 2020

@StefanKarpinski do you have an opinion on whether it would be ok to automatically install the package if it isn't available yet?

@tkf
Copy link
Member

tkf commented Apr 16, 2020

+1 for installing BugReporting.jl in an isolated temporary environment. It's conceivable that some bugs manifest in particular versions of packages (e.g., JSON.jl) that are incompatible with BugReporting.jl. It'd be nice to be able to confidently use rr even in such cases.

Also, it doesn't have to be temporary, does it? Why not use ~/.julia/environments/v1.x-bug-report?

@StefanKarpinski
Copy link
Member

Maybe check if it already exists in the current load path and if not, create a temporary environment, put it at the front of the load path, add BugReporting in it and use it, then when done, delete the environment. Deleting and recreating should be no big deal since the environment is just a directory with a project and manifest in it, the actual installed copy of the package will stay around until it's garbage collected.

Why check for BugReporting in the current load path first? Because otherwise it's impossible for the user to explicitly control what version of BugReporting to use, which might sometimes be desirable.

@Keno
Copy link
Member Author

Keno commented Apr 16, 2020

Now with auto-installation as suggested by @StefanKarpinski (should work as soon as the package is registered). BTW, I'd appreciate if people try out the workflow in the meantime and give feedback.

@Keno
Copy link
Member Author

Keno commented Apr 17, 2020

Unless there's further comments, I'll plan to merge this once the package registration goes through.

return mktempdir() do tmp
prev_active = Base.ACTIVE_PROJECT[]
env_path = joinpath(tmp, "TmpForBugReporting")
Pkg.generate(env_path)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you generate a package here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just delete it from here.

let Pkg = Base.require(Base.PkgId(
Base.UUID((0x44cfe95a_1eb2_52ea,0xb672_e2afdf69b78f)), "Pkg"))
return mktempdir() do tmp
prev_active = Base.ACTIVE_PROJECT[]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to handle the case where @ is not in the load path you need something like

old_load_path = copy(LOAD_PATH)
push!(empty!(LOAD_PATH), tmp)
Pkg.add(...)
BugReporting = Base.require(...)
append!(empty!(LOAD_PATH), old_load_path)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't it still need at least some project?
Without that

ERROR: no active project
Stacktrace:
 [1] pkgerror(::String) at /home/keno/julia-rebase/usr/share/julia/stdlib/v1.5/Pkg/src/Types.jl:52
 [2] find_project_file(::Nothing) at /home/keno/julia-rebase/usr/share/julia/stdlib/v1.5/Pkg/src/Types.jl:180

I'm happy to do whatever the recommended thing here, is, but I think I'll go ahead and merge as is, since it seems to work ok. Would appreciate a PR to do it the proper way :)

Recently I've been asking people to send me rr recordings whenever
they encounter bugs, since it really streamlines the bug fixing process
(in particular, it cuts out the whole "get it to reproduce and capture
it in rr part of the process"). However, the process so far is not quite
trivial. You have to get rr from somewhere (in a version that isn't broken
for latest julia), you have to remember to pack it and then you have
to find a place to upload it. I put together a package
(https://github.com/Keno/BugReporting.jl) that takes care of all of these
steps, but the convenience isn't quite 100% yet. That's what this PR is
supposed to address. It adds `--bug=` command line flag that internally
loads up the BugReporting, but passes through all the command line
options, environment, etc. The idea is that to create a bug report
you just do all the things you usually do, but instead of launching
`julia`, you launch `julia --bug`. This should also work if you are
launching Julia from within a script, etc.

Demo: https://asciinema.org/a/JFdoGT2wlxBE7uyzM1ZjwgSA5
@Keno Keno merged commit 1d64823 into master Apr 20, 2020
@Keno Keno deleted the kf/bugcmd branch April 20, 2020 22:31
@KristofferC
Copy link
Member

Tried to use it for #35014:

kristofferc@arctic3:~/julia$ cat ccallable.jl                                                                                                                                        
Base.@ccallable function f()::Cint
    return 0
end

kristofferc@arctic3:~/julia$ ./julia --bug-report=rr --output-o="sys.o" --sysimage="usr/lib/julia/sys.so" ccallable.jl
┌ Info: Loading BugReporting package...
└ @ InteractiveUtils /home/kristofferc/julia/usr/share/julia/stdlib/v1.5/InteractiveUtils/src/InteractiveUtils.jl:355
┌ Info: Package `BugReporting` not found - attempting temporary installation
└ @ InteractiveUtils /home/kristofferc/julia/usr/share/julia/stdlib/v1.5/InteractiveUtils/src/InteractiveUtils.jl:361

signal (11): Segmentation fault
in expression starting at none:0
uv_write2 at /workspace/srcdir/libuv/src/unix/stream.c:1397
uv_write at /workspace/srcdir/libuv/src/unix/stream.c:1492
jl_uv_write at /home/kristofferc/julia/src/jl_uv.c:463
uv_write_async at ./stream.jl:962
uv_write at ./stream.jl:919
unsafe_write at ./stream.jl:1002
write at ./strings/io.jl:183 [inlined]
print at ./strings/io.jl:185 [inlined]
#with_output_color#741 at ./util.jl:90
with_output_color##kw at ./util.jl:70 [inlined]
#printstyled#742 at ./util.jl:104 [inlined]
printstyled##kw at ./util.jl:104
_jl_invoke at /home/kristofferc/julia/src/gf.c:2235 [inlined]
jl_apply_generic at /home/kristofferc/julia/src/gf.c:2402
display_error at ./client.jl:102
_jl_invoke at /home/kristofferc/julia/src/gf.c:2235 [inlined]
jl_apply_generic at /home/kristofferc/julia/src/gf.c:2402
display_error at ./client.jl:106
_jl_invoke at /home/kristofferc/julia/src/gf.c:2235 [inlined]
jl_apply_generic at /home/kristofferc/julia/src/gf.c:2402
jl_apply at /home/kristofferc/julia/src/julia.h:1691 [inlined]
do_apply at /home/kristofferc/julia/src/builtins.c:650
jl_f__apply_latest at /home/kristofferc/julia/src/builtins.c:700
#invokelatest#1 at ./essentials.jl:710 [inlined]
invokelatest at ./essentials.jl:709 [inlined]
_start at ./client.jl:508
unknown function (ip: 0x7f8c8c167fbb)
_jl_invoke at /home/kristofferc/julia/src/gf.c:2235 [inlined]
jl_apply_generic at /home/kristofferc/julia/src/gf.c:2402
jl_apply at /home/kristofferc/julia/ui/../src/julia.h:1691 [inlined]
true_main at /home/kristofferc/julia/ui/repl.c:96
main at /home/kristofferc/julia/ui/repl.c:217
__libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
_start at ./julia (unknown line)
Allocations: 1732831 (Pool: 1732093; Big: 738); GC: 2
Segmentation fault (core dumped)

Perhaps it doesn't like the --output-o environment.

@KristofferC
Copy link
Member

Error might be because --output-o doesn't initialize LOAD_PATH etc so the bug reporting package probably fails to load

@KristofferC
Copy link
Member

Now I tried to run it for #35580 but got:


julia> testcrash(2:40)
(s, Amatrix ≈ Amatrix) = (2, true)
...
(s, Amatrix ≈ Amatrix) = (30, true)
(s, Amatrix ≈ Amatrix) = (31, true)
julia: /home/kc/julia/src/codegen.cpp:2779: jl_cgval_t emit_invoke(jl_codectx_t&, jl_expr_t*, jl_value_t*): Assertion `jl_is_method_instance(mi)' failed.

signal (6): Aborted
in expression starting at REPL[3]:1
gsignal at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
abort at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x7fc3fd1a0768)
__assert_fail at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
emit_invoke at /home/kc/julia/src/codegen.cpp:2779
emit_expr at /home/kc/julia/src/codegen.cpp:3637
emit_ssaval_assign at /home/kc/julia/src/codegen.cpp:3348
emit_stmtpos at /home/kc/julia/src/codegen.cpp:3512
emit_function at /home/kc/julia/src/codegen.cpp:6173
jl_emit_code at /home/kc/julia/src/codegen.cpp:6519
jl_emit_codeinst at /home/kc/julia/src/codegen.cpp:6553
jl_compile_workqueue at /home/kc/julia/src/codegen.cpp:6645
_jl_compile_codeinst at /home/kc/julia/src/jitlayers.cpp:100
jl_generate_fptr at /home/kc/julia/src/jitlayers.cpp:277
jl_compile_method_internal at /home/kc/julia/src/gf.c:1968
jl_compile_method_internal at /home/kc/julia/src/gf.c:1935 [inlined]
_jl_invoke at /home/kc/julia/src/gf.c:2228 [inlined]
jl_apply_generic at /home/kc/julia/src/gf.c:2402
macro expansion at ./show.jl:618 [inlined]
testcrash at ./REPL[2]:4
...
ERROR: failed process: Process(setenv(`/home/kc/.julia/artifacts/48921513a6ad5f8e18bea39041ae9757ac025a86/bin/rr record /home/kc/julia/usr/bin/julia -Cnative -J/home/kc/julia/usr/lib/julia/sys.so -g1`,["_CE_M=", "LSCOLORS=Gxfxcxdxbxegedabagacad", "PATH=/home/kc/.julia/artifacts/7ccad40eed5c2667a772729db5d53707449f27ae/bin:/home/kc/.julia/artifacts/48921513a6ad5f8e18bea39041ae9757ac025a86/bin:/home/kc/miniconda3/condabin:/home/kc/.cargo/bin:/home/kc/perl5/bin:/usr/lib/cuda/bin:/home/kc/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/texlive/2019/bin/x86_64-linux:/usr/local/texlive/2019/bin/x86_64-linux:/home/kc/.fzf/bin", "EDITOR=nvim", "PERL_MM_OPT=INSTALL_BASE=/home/kc/perl5", "LD_LIBRARY_PATH=/home/kc/julia/usr/bin/../lib/julia:/home/kc/julia/usr/bin/../lib:/home/kc/.julia/artifacts/7ccad40eed5c2667a772729db5d53707449f27ae/lib:/usr/lib/cuda/lib64", "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus", "PERL5LIB=/home/kc/perl5/lib/perl5", "XDG_SESSION_TYPE=tty", "USER=kc"  …  "PWD=/home/kc/julia", "_RR_TRACE_DIR=/home/kc/.julia/artifacts/jl_uSQtHM", "SSH_CONNECTION=::1 57742 ::1 22", "OPENBLAS_NUM_THREADS=8", "XDG_SESSION_ID=239", "KEYTIMEOUT=1", "PERL_MB_OPT=--install_base \"/home/kc/perl5\"", "FZF_DEFAULT_COMMAND=rg --files --no-ignore-vcs --hidden", "LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:", "OPENBLAS_MAIN_FREE=1"]), ProcessSignaled(6)) [0]

Stacktrace:
 [1] pipeline_error at ./process.jl:525 [inlined]
 [2] run(::Cmd; wait::Bool) at ./process.jl:440
 [3] run at ./process.jl:438 [inlined]
 [4] (::BugReporting.var"#3#6"{String,Array{Any,1}})(::String) at /home/kc/.julia/packages/BugReporting/IhWWq/src/BugReporting.jl:43
 [5] (::rr_jll.var"#8#9"{BugReporting.var"#3#6"{String,Array{Any,1}}})() at /home/kc/.julia/packages/rr_jll/WeS5I/src/wrappers/x86_64-linux-gnu-cxx11.jl:35
 [6] withenv(::rr_jll.var"#8#9"{BugReporting.var"#3#6"{String,Array{Any,1}}}, ::Pair{String,String}, ::Vararg{Pair{String,String},N} where N) at ./env.jl:161
 [7] rr(::BugReporting.var"#3#6"{String,Array{Any,1}}; adjust_PATH::Bool, adjust_LIBPATH::Bool) at /home/kc/.julia/packages/rr_jll/WeS5I/src/wrappers/x86_64-linux-gnu-cxx11.jl:34
 [8] rr at /home/kc/.julia/packages/rr_jll/WeS5I/src/wrappers/x86_64-linux-gnu-cxx11.jl:18 [inlined]
 [9] #2 at /home/kc/.julia/packages/BugReporting/IhWWq/src/BugReporting.jl:39 [inlined]
 [10] create_artifact(::BugReporting.var"#2#5"{Array{Any,1}}) at /home/kc/julia/usr/share/julia/stdlib/v1.5/Pkg/src/Artifacts.jl:214
 [11] make_interactive_report(::String, ::Array{Any,1}) at /home/kc/.julia/packages/BugReporting/IhWWq/src/BugReporting.jl:38
 [12] make_interactive_report(::String) at /home/kc/.julia/packages/BugReporting/IhWWq/src/BugReporting.jl:30

@Keno
Copy link
Member Author

Keno commented Apr 24, 2020

Whoops, we of course need to ignorestatus the rr code, so it doesn't interrupt julia. The good news is that your recording should be stored, and you should be able to manually pass the directory it printed at the beginning to BugReporting.upload_rr_trace. Thanks for giving it a whirl!

@KristofferC
Copy link
Member

KristofferC commented Apr 24, 2020

It printed

rr: Saving execution to trace directory `/home/kc/.julia/artifacts/jl_uSQtHM/julia-0'.

but there is no such folder / file.

@staticfloat
Copy link
Member

It most likely got cleaned up by the mktempdir().

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.

8 participants