Trying to fix a dynamic lib bug in the compiler: can I use cargo to `git bisect` in the rust repo?


#1

First, some background:

I’m trying to fix a rust bug which I’ve reported here. The short description of the bug is that loading a new version of a dynamic library while the program was still running worked in 1.19.0, but now doesn’t work in 1.20.0.

Why would I want to do such a weird thing? If there is a problem with my program that is only apparent when the program is in a particular state that takes time to reach, then if I can reload the code responsible at runtime, I can quickly try different options and see their effects instantly (modulo compilation time). I don’t need to manually put the program back in the problematic state. It’s really nice having such a tight feedback loop, but right now it doesn’t work.

I haven’t dug around in the compiler before, so I’m trying to find the commit that introduced problem by using git bisect. If you hand git bisect run a command which exits with code 0 only when the code is good, it will find which commit the bug happened in.

Because the nature of the bug requires at least two crates to replicate, (and in the automated case, at least three,) and because I’m currently using hardcoded paths based on where cargo puts things, it would be nice if I could still use cargo with a given rust commit’s version of rustc. Is this possible or will I have to make a version that can be run with just rustc and a shell script?


#2

Cargo will use the RUSTC environment variable, so you could set that to something like:
[path-to-rustc-src]/build/[host-triple]/stage2/bin/rustc


#3

I’ve also written https://github.com/Mark-Simulacrum/bisect-rust which may be of use to you. I’m not sure if the specific bug you’re looking to bisect will work with that tool, but I’d be happy to take a PR or possibly explore fixing something myself too. Let me know if you have any questions!


#4

My bug happens only at run-time, and as far as I could tell, bisect-rust seems to be only for compile-time errors. Unless there’s a straightforward way to configure the test script to work with a run-time bug reproduction I’m not seeing?


#5

That seems to be working fine. Rust takes a long time to build on my old only-2-cores machine, so after a few attempts where I messed up the shell script, (every run was producing an error) it’s still running now.

I’m (hopefully) saving some time using stage1 only. Most of the time seems to be spent building the llvm submodule. Does anyone know a way that could be cached between the different builds git bisect run does? Would using an installed rustc as the stage0 compiler a) be viable, b) speed up the build significantly?


#6

You could try using an external LLVM build – ./configure --llvm-root=/path. Rust 1.19 and 1.20 both use LLVM 4.0. If you can still reproduce the problem using the same LLVM, then you’ve ruled that out of the regression, so bisect with that.

External stage0 won’t save much time, just avoiding snapshot downloads that are cached anyway.


#7

Scratch that, that isn’t working, at least the way I’ve been trying to use it. To work around the bug I’ve been switching back to 1.19.0 occasionally so it took a while to notice it was just using my installed rustc! I’ve been using this script with the rust repo and my example checked out in adjacent folders. Is there something obviously wrong with the script I’m not seeing?


#8

You probably need an absolute path for RUSTC. The ./rust/... relative path is bogus as soon as you cd. It also needs an export from the shell, otherwise cargo will never even see it, which I guess is why the relative path didn’t blow up on you.


#9

Thanks for your help! I’ve exported an absolute path in the script and now it gives the same answer for a test commit whether my default is 1.19.0 or 1.20.0. Hopefully the bisection I’m setting up now will actually find the bug!