What is Rusts (or LLVMs) stance on reading the stack?

Long story short, I would like to read all data on the stack, or at least the parts from main until wherever. valgrind has not been very happy about this, but I've figured that I have just been a little bit off. Now, I'm not so sure, as I suppose there might be a lot of stuff on the stack that we're not supposed to read. This leads me to my topic: is this simply a lost cause and will forever and ever be UB and my program will end up ordering 1000 kg of bananas from Amazon, or do I just risk reading some strange values, and that's that?

Similarly, is it alright to cast a usize to some ptr type, if it just happens to actually be valid? Or are there some UB traps here as well?

https://github.com/alexcrichton/backtrace-rs

Look at this library, it can be used to get backtraces.
The library reads the stack to do so, so you can get some inspiration from it.

1 Like

That seems sort of close to what I want, but not quite. If I'm not mistaken, the library only handles frames in the call stack. What I'd like is a way to look at all the bytes existing on all stack frames from a function, all the way down to main (or wherever the execution entry point for that thread was).

LLVM requires the following:

Any memory access must be done through a pointer value associated with an address range of the memory access, otherwise the behavior is undefined.
~ LLVM Language Reference Manual — LLVM 18.0.0git documentation

My (limited) understanding of them is that they're what allow LLVM to remove local variables, for example, since they make it disallowed to just conjure up the address of a local without using its address to do so. (You can't take the address of one local and offset it to try and find another local.)

Why exactly are you trying to read the stack? What do you hope to accomplish? Without debuginfo, there's no way to know how to interpret what you find anyway, and there's no stability guarantee about what you'll find there.

1 Like

Why exactly are you trying to read the stack?

I'm trying to implement a garbage collector[1]. The general idea is to scan the stack for possible heap pointers, looking for allocated memory that is no longer reachable. By using a few other tricks, this becomes feasible under certain conditions.

Without debuginfo, there’s no way to know how to interpret what you find anyway,

This is actually fine, in a sense. I would just like to know if certain values are stored anywhere on the stack.

and there’s no stability guarantee about what you’ll find there.

Yeah, this is slightly annoying, but for this project it should be alright. AFAIK no programming language have this written in stone anyways, and the reason GCs work is because they're a part of the runtime, so they actually to know how the memory is laid out.

[1]: Website not found!

1 Like

Funny I am actually also just implementing a garbage collector.

Mine does not rely on guessing possible Gc`d values, but rather adds a new smart pointer, and implements tracing for all collections in std + a custom derive.

I am currently trying to figure out, how to manage Gc instances (thread local / global), and also how to interact with other crates using the gc.