-
Notifications
You must be signed in to change notification settings - Fork 183
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
how to pretty print Decimal value at debug time? #510
Comments
This is an interesting one as it seems that lldb prints the struct layout by default. In essence, it's related to #204 To simplify:
The lldb debugger prints the following:
Unfortunately, this is a limitation of the pretty printers at the moment. I think it's unlikely to patch the providers directly for Rust Decimal, hence I'm hoping a more extensible method will eventually land. For the meantime, if you're using windows you may be able to leverage |
Unfortunately, I use macos. Do I have an option? I cannot even call methods at debug time... |
Unfortunately, there is no easy solution right now. The ideal solution would be to be able to implement In lieu of that, we may be able to write an |
I think debugger extensions could work, even though RFC3191 is still only in nightly rust. Can put something like this to #![debugger_visualizer(gdb_script_file = "../gdb/rust-decimal-gdb.py")] |
Thank You @theonekeyg Where is this "../gdb/rust-decimal-gdb.py" file? Should I put this line in the rust-decimal project, or in my project? I need this for lldb. I am on macos. |
@ebadta81 I assume this file doesn't exist yet, this was addressed to @paupino as a feature proposal that would solve this issue. Really looking forward to solve this |
Since the Copy the following python code into a file import lldb
import decimal
class RustDecimalProvider(object):
"Print a rust_decimal::Decimal"
def __init__(self, valobj, internalDict):
self.valobj = valobj
self.lo = self.valobj.GetChildMemberWithName('lo').GetValueAsUnsigned()
self.mid = self.valobj.GetChildMemberWithName('mid').GetValueAsUnsigned()
self.hi = self.valobj.GetChildMemberWithName('hi').GetValueAsUnsigned()
self.flags = self.valobj.GetChildMemberWithName('flags').GetValueAsUnsigned()
self.scale = (self.flags & 0x00FF0000) >> 16
self.sign = self.flags >> 31
def num_children(self):
return 1
def get_child_index(self, name):
return 0
def get_child_at_index(self, index):
child_type = self.valobj.target.GetBasicType(lldb.eBasicTypeChar)
byte_order = self.valobj.GetData().GetByteOrder()
data = lldb.SBData.CreateDataFromCString(byte_order, child_type.GetByteSize(), self.build_decimal())
return self.valobj.CreateValueFromData("Decimal", data, child_type.GetArrayType(data.GetByteSize()))
def update(self):
return True
def has_children(self):
return True
def build_decimal(self):
mantissa = decimal.Decimal(self.hi)
shift = decimal.Decimal(4294967296)
mantissa = (mantissa * shift) + decimal.Decimal(self.mid)
mantissa = (mantissa * shift) + decimal.Decimal(self.lo)
value = mantissa
divisor = decimal.Decimal(10)
for i in range(self.scale):
value = value / divisor
if self.sign > 0:
value = value * -1
return str(value)
def __lldb_init_module(debugger, dict):
debugger.HandleCommand(
'type synthetic add -x "Decimal" --python-class decimal_printer.RustDecimalProvider -w Rust') To configure this you'd need to load this into your LLDB context via:
Of course, to avoid having to do this every time, you can add a line into your
|
For verboseness, the example above was the following code: use rust_decimal::prelude::*;
struct Wrapper {
value: Decimal
}
fn main() {
let value = Decimal::new(1234, 3);
let value = Wrapper { value };
do_something(value);
}
fn do_something(value: Wrapper) {
println!("{}", value.value);
} I started the program using
Once in LLDB, I set a breakpoint:
We then started the program:
Once the breakpoint was hit we can see the two different outcomes. Before we load the pretty printer:
After we load the pretty printer:
|
This is stabilised and the docs on how to do so are available here. I suspect the MR to do this should be pretty easy for GDB given the text above. Although adding testing for it might be harder? |
There might be a rather easy solution. Add a feature flag which extends the structure to contain an approximate f64 representation of the decimal, update it every time the decimal state changes. That way we can inspect it during debug and it has no relevancy or overhead without the feature flag. It might also be bound to debug compile, but i think it should at least be guarded via a feature flag. |
Hello,
I have read #126 but it doesn't help me.
I use Decimal in a VecDeque field.
How can I see the actual numbers at debug?
I use lldb and vscode.
The text was updated successfully, but these errors were encountered: