-
Notifications
You must be signed in to change notification settings - Fork 103
Include ruby class names in frame name output for ruby 3.3.0+ #397
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
Conversation
| ) | ||
| ); | ||
|
|
||
| macro_rules! get_stack_frame_3_3_0( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The classext approach used here is only valid in ruby 3.3.0+, it may be possible to get the info in another way in earlier versions, but the struct i'm using wasn't added until 3.3.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ).context("couldn't get ruby string from iseq body")?; | ||
|
|
||
| let method_name = get_ruby_string(body.location.label as usize, source)?; | ||
| let name = if class_name != "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again this is a bit lazy but it is simple for composing the class name with the method name.
I guess it needs to be a bit smarter to match https://github.com/ruby/ruby/blob/master/vm_backtrace.c#L1974-L1975, and check if it is a singleton or not and use "." instead of "#"? I'll see if i can add that easily enough, seems like it uses a bitmask on the flags attribute or something?
|
@acj when you have a sec, please take a look! I was hoping to have more complete tests but as i said in the desc, couldn't get the coredump tests to work for a new coredump with a more complete test file. Technically the 3.3.0 test is updated and includes classes for the top level methods (eg, aaa -> Object#aaa), but i wanted to have something with nested classes, etc. as i mentioned in rbspy/rbspy-testdata#7 |
|
FYI i think there is a legit issue here, but haven't pinned it down yet - the issue i'm seeing with the coredump tests seems to be related to reading the class name. We might need some more checks for safety, will try and repro more locally. |
Ok i think i've fixed this, I also refactored reading the class names into their own function, and improved the error handling. |
Cargo.toml
Outdated
| [dev-dependencies] | ||
| byteorder = "1.4.3" | ||
| rbspy-testdata = "0.2.2" | ||
| rbspy-testdata = { git = "https://github.com/dalehamel/rbspy-testdata.git", branch = "class-data" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally we'd land this patch first, release a new version, then update this before merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just tagged and published 0.2.4 with the enriched 3.3.0 coredump.
| ) | ||
| ); | ||
|
|
||
| macro_rules! get_ruby_string_array_3_3_0( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needed to add these as I was getting a string allocation error when trying to read the absolute path in my coredump, rstring was reporting its size as enormous (might have been reported as max string length, or max string length -1?)
I added a sanity test where we can read the value only if it doesn't exceed a maximum size, and then pass 4096 as that is the maximum path size on linux.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. There are a few places in the code where we're defensive about unreasonably large values, either clamping them to a sane value or dropping them depending on the situation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test ui::summary::tests::stats_by_line_number ... ok
memory allocation of 139633090689240 bytes failed
error: test failed, to rerun pass `--lib`
Caused by:
process didn't exit successfully: `/home/runner/work/rbspy/rbspy/target/x86_64-unknown-linux-gnu/release/deps/rbspy-310591bc6f33f4f3` (signal: 6, SIGABRT: process abort signal
Hmm another test failure with this memory allocation issue... but it doesn't seem related to the code change here 🤨 looks like another function might need to add the maximum string read
| let rel_path = get_ruby_string(path_addr, source)?; | ||
| // In the case of internal ruby functions (and maybe others), we may not get a valid | ||
| // pointer here | ||
| let abs_path = get_ruby_string_limit(abs_path_addr, 4096, source) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function is identical to 3_2 except for this line.
|
freebsd failure seems like a flake |
|
I think the FreeBSD failure is a workflow bug that I introduced recently. I'll take a closer look. |
|
Okay, the CI bug should be fixed on main, so please rebase. I ran your branch here with the testdata version bump and everything was green. I need to review the version-specific code more closely and do some local testing, but I'm optimistic that we'll be able to merge this in the next week. Thanks for working on it! |
a41043e to
cc6de92
Compare
|
Thanks @acj
FYI looks like you only fixed that on your fork, didn't push to main on rbspy/rbspy yet. I fetched and rebased your main though.
Awesome, I moved the testdata back to the versioned crate. Commit looks the same as acj@9cb6983, including the lockfile bumps.
Sounds great! Please give it a good look and if you can, try it on a real workload - I haven't had a chance to yet. |
acj
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has worked well in my local testing. I'll try to find a good production load to test it on this week, but that doesn't need to hold us up.
Fixes #379
Updates bindgen ruby structs for 3.3.0+ to include the necessary structs for parsing out the class name. 3.3.0 was the first release to include ruby/ruby@abff5f6, which makes looking up the classpath trivial compared to prior versions, where it was stored as an instance variable.
I used the method that @acj had been pursuing in his comment on #379, but updated it for ruby refactoring over the last 2 years. I copied the algorithm that ruby/ruby is doing, I was able to leverage some code that already existed for checking the method entry for c functions.
Note - I had to update the test fixtures / sample stacks for ruby 3.3.0+ as they now include the class name! (
Object#, defined at the top level).Here's a basic test program, and i've added a more complete one in rbspy/rbspy-testdata#7, but I had to fix a bug in how we were reading the absolute path in order to get that to work.