Live data from Hacker News

rr – record and replay debugger for C/C++

rr-project.org

81–90 of 134 posts

Re: rr – record and replay debugger for C/C++

#81
post #2

rr is really cool, but almost every time I have decided to pull it out as one of the "big guns" it turns out that I have a concurrency bug and so rr is unable to reproduce it. Despite that, it would be very, very, very cool if some languages built rr directly into their tooling. Obviously you can always "just" use rr/gdb, but imagine if rr invocations were as easy to set up and do as pdb is in Python!

Another thing that rr sadly doesn't support is GPUs. I'd love to use it but most of my stuff involves GPUs in some way or another.

Re: rr – record and replay debugger for C/C++

#82
post #58

Earlier quoted context omitted.

You can, but that makes the type system worse. Also depending on how these few bytes are used, they can add up and drag down performance.

Copying a bunch of stuff because the borrow checker won't let you share it can drag down performance as well. Yes, I do understand why one might conclude that tradeoff is worth it. But it is a tradeoff.

The original topic was the abstraction ceiling. There are a bunch of abstractions which C++ just can't express.

Re: rr – record and replay debugger for C/C++

#83
post #78

Earlier quoted context omitted.

That sounds very interesting; Do you have a write-up on this that you are willing to share?

This is the usual killer feature of something like rr. You debug, look at some variable: `p whatever`. You see that its value is wrong. You want to know where this wrong value came from, so you `watch -l whatever` and `rc`. Bam!

There are some bugs I would never have figured out without this technique. It feels like cheating.

Re: rr – record and replay debugger for C/C++

#84

Has anyone gotten rr to work with opengl or vulkan? It seems to always crash for me after making an opengl call.

VirGL might help, it redirects OpenGL calls over a socket. Start virgl_test_server and run your app with extra environment vars __GLX_VENDOR_LIBRARY_NAME=mesa LIBGL_ALWAYS_SOFTWARE=1 GALLIUM_DRIVER=virpipe

Re: rr – record and replay debugger for C/C++

#85
post #21

Earlier quoted context omitted.

Recently the federal government issued a security advisory encouraging all new development to be done in Rust. I'm not sure the extent of which agencies this was meant to cover but it struck me as very unrealistic having just done years of java development for a state agency. https://www.nextgov.com/cybersecurity/2024/02/white-house-ur...

It doesn't say that, no. Even in the title it says "memory-safe languages", which of course includes Java. Rust is "only" mentioned in the context of a C / C++ replacement, which tends to be a different area.

Yes that is correct, I had read a different article that had a more rust first focus. I just tried to google for a reference to the news release I was referencing, but yea it doesn't really support my comment :(

Re: rr – record and replay debugger for C/C++

#86
post #46

Earlier quoted context omitted.

> There's a bit of a higher abstraction ceiling in Rust Compared to C, yes, but not compared to C++.

This isn't really true. Rust has a much better type system. When writing generic code the impact is enormous. C++ doesn't have a real Empty Type, and it thinks Units have non-zero size. In practical terms this makes it incredibly wasteful and in terms of a clear abstraction it encourages you to come up with a hack that's unclear but efficient.

C++20 added `[[no_unique_address]]`, which lets a `std::is_empty` field alias another field, so long as there is only 1 field of that `is_empty` type. https://godbolt.org/z/soczz4c76 That is, example 0 shows 8 bytes, for an `int` plus an empty field. Example 1 shows two empty fields with the `int`, but only 4 bytes thanks to `[[no_unique_address]]`. Example 2 unfortunately is back up to 8 bytes because we have two empty fields of the same type...

`[[no_unique_address]]` is far from perfect, and inherited the same limitations that inheriting from an empty base class had (which was the trick you had to use prior to C++20). The "no more than 1 of the same type" limitation actually forced me to keep using CRTP instead of making use of "deducing this" after adopting c++23: a `static_assert` on object size failed, because an object grew larger once an inherited instance, plus an instance inherited by a field, no longer had different template types.

So, I agree that it is annoying and seems totally unnecessary, and has wasted my time; a heavy cost for a "feature" (empty objects having addresses) I have never wanted. But, I still make a lot of use of empty objects in C++ without increasing the size of any of my non-empty objects.

C++20 concepts are nice for writing generic code, but (from what I have seen, not experienced) Rust traits look nice, too.

Re: rr – record and replay debugger for C/C++

#87
post #58

Earlier quoted context omitted.

You can, but that makes the type system worse. Also depending on how these few bytes are used, they can add up and drag down performance.

Copying a bunch of stuff because the borrow checker won't let you share it can drag down performance as well. Yes, I do understand why one might conclude that tradeoff is worth it. But it is a tradeoff.

Funnily enough, because the borrow checker is so strict I feel more confident writing complex borrowing logic that I wouldn't dare attempting in C or C++ because even if I were to get everything right (a big if), there's no assurance that a later refactor wouldn't subtilty break the code. The borrow checker sometimes makes you copy data that you thought you didn't, but more often than not it is enforcing an actual edge case that would have been a bug, had the borrow checker not be present. If the copy is indeed so critical, you can also ease your pain with runtime checks instead using Rc/Arc, but that's another discussion.

Re: rr – record and replay debugger for C/C++

#88

Is it truly only for C/C++? My limited understanding says a debugger needs: a list of symbols (.pdb files on windows, can't remember what they are on linux), understanding of syscalls and a few other similar things. I thought they don't care too much what generated the binaries they are debugging (obviously as long as it's native code). Doesn't rr work with other languages like rust, zig, odin, nim, and similar ones?…

People use it for rust: https://bitshifter.github.io/rr+rust/index.html#1

Re: rr – record and replay debugger for C/C++

#89
post #86

Earlier quoted context omitted.

This isn't really true. Rust has a much better type system. When writing generic code the impact is enormous. C++ doesn't have a real Empty Type, and it thinks Units have non-zero size. In practical terms this makes it incredibly wasteful and in terms of a clear abstraction it encourages you to come up with a hack that's unclear but efficient.

C++20 added `[[no_unique_address]]`, which lets a `std::is_empty` field alias another field, so long as there is only 1 field of that `is_empty` type. https://godbolt.org/z/soczz4c76 That is, example 0 shows 8 bytes, for an `int` plus an empty field. Example 1 shows two empty fields with the `int`, but only 4 bytes thanks to `[[no_unique_address]]`. Example 2 unfortunately is back up to 8 bytes because we have two em…

It's probably mean for me to say "empty type" to C++ people because of course just as std::move doesn't move likewise std::is_empty doesn't detect empty types. It can't because C++ doesn't have any.

You may need to sit down. An empty type has no values. Not one value, like the unit type which C++ makes a poor job of as you explain, but no values. None at all.

Because it has no values we will never be called upon to store one, we can't call functions which take one as a parameter, operations whose result is an empty type must diverge (ie control flow escapes, we never get to use the value because there isn't one). Code paths which are predicated on the value of an empty type are dead and can be pruned. And so on.

Rust uses this all over the place. C++ can't express it.

Re: rr – record and replay debugger for C/C++

#90
post #9
post #6

Perhaps worth mentioning is that someone attempted to port this to Rust and got about 60,000 lines of code into it before archiving the project. I feel like comparing these two efforts would be an interesting case study on the impacts / benefits / limitations or difficulties, etc involved in rewriting from C++ to Rust. https://github.com/sidkshatriya/rd/

I don't understand the "rewrite X/Y/Z in Rust" trend that has been going for a few years. I'm not familiar with Rust, but I'm almost sure it has a good C interoperability. If a certain piece of software is working well, what is the benefit of rewriting it in Rust?

> If a certain piece of software is working well, what is the benefit of rewriting it in Rust?

One benefit is it's easier to hide malicious code thanks to Rust's complicated syntax.

Post reply on HN