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
Include JIT information in crash reports #5872
Conversation
Context is we want to do this next chrisseaton@38b904d. |
a6a6198
to
4884eab
Compare
version.c
Outdated
if (strlcat(new_description, " +MJIT", dynamic_description_max) >= dynamic_description_max) { | ||
goto description_string_overflow; | ||
} |
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.
It seems that it should be possible to select between two string literals like the old code and avoid the need to use strlcat
. Is there some particular reason you picked this approach?
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 context here is I'm trying to make it possible to add as many of these flags as we want. So three possible combinations is easy, but if I had another flag, independent of the two JIT flags, now I need six literals, etc.
The particular flag I want to add is +MMTk
for the GC we're integrating.
I think these flags are very useful for these kind of major features, which completely change how you're debugging a crash or something, which is why we want them so prominent in the description and version string.
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.
Ah okay, since the badges are infix some string building seems unavoidable. I think you could make this function shorter by picking between an empty string and the +...
string for each badge and ending with a single call to snprintf
. Bonus for avoiding the non ISO strlcat
. You might also want to switch to a statically sized buffer instead of calling malloc. A size computed by summing sizeof(...)
should be suitable for sizing a static character array.
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.
Also, since MMTK is not part of Ruby (yet), I'm tempted to keep the current simpler setup. Since MMTK will need to patch this function anyways maybe the string complexity should be in that patch instead of in this repo.
e5d3cd3
to
dd83f17
Compare
@XrXr could I get you to re-review and re-consider merging without MMTk? In getting all the tests passing I've realised it's got a benefit right now - the crash reporter currently uses the default description, without the flags. That's because I guess they don't want to run any logic while handling a crash. But my approach runs the logic up-front to change the stored description, so a crash after a certain point will get the flags without having to run any logic. Before:
After:
Seems like a crash is exactly when you want to see these flags! I also simplified the logic as you suggested to use |
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 think it's useful to have +YJIT
in crash reports whenever appropriate. It could be inferred from the process memory map, but it doesn't hurt to be clearer.
error.c | 8 ++++----
include/ruby/version.h | 3 ++-
ruby.c | 8 +++++---
test/-ext-/bug_reporter/test_bug_reporter.rb | 2 --
test/ruby/test_rubyoptions.rb | 2 +-
version.c | 37 +++++++++++++++++--------------------
6 files changed, 29 insertions(+), 31 deletions(-)
The patch deletes more line than adds, so I think this change pays for itself in terms of complexity.
Ok that still de-duplicates the logic for choosing between descriptions so will be easier to merge what I want with MMTk. |
version.c
Outdated
void | ||
Init_ruby_description(void) | ||
{ | ||
VALUE description = rb_obj_freeze(rb_usascii_str_new_cstr(ruby_dynamic_description)); |
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.
VALUE description = rb_obj_freeze(rb_usascii_str_new_cstr(ruby_dynamic_description)); | |
const char *desc = ruby_dynamic_description; | |
VALUE description = rb_obj_freeze(rb_usascii_str_new_static(desc, (long)strlen(desc))); |
Why needs to separate void
Init_ruby_description(void)
{
VALUE description;
if (MJIT_OPTS_ON) {
ruby_dynamic_description = ruby_description_with_mjit;
description = MKSTR(description_with_mjit);
}
else if (rb_yjit_enabled_p()) {
ruby_dynamic_description = ruby_description_with_yjit;
description = MKSTR(description_with_yjit);
}
else {
description = MKSTR(description);
}
/*
* The full ruby version string, like <tt>ruby -v</tt> prints
*/
rb_define_global_const("RUBY_DESCRIPTION", /* MKSTR(description) */ description);
} |
I left definition of |
I don't think it is a significant difference if the constant is defined earlier a little. |
It might be better If we pass whether MJIT is on into |
Since enabling YJIT or MJIT drastically changes what could go wrong at runtime, it's good to be front and center about whether they are enabled when dumping a crash report. Previously, `RUBY_DESCRIPTION` and the description printed when crashing can be different when a JIT is on. Introduce a new internal data global, `rb_dynamic_description`, and set it to be the same as `RUBY_DESCRIPTION` during initialization; use it when crashing. * version.c: Init_ruby_description(): Initialize and use `rb_dynamic_description`. * error.c: Change crash reports to use `rb_dynamic_description`. * ruby.c: Call `Init_ruby_description()` earlier. Slightly more work for when we exit right after printing the description but that was deemed acceptable. * include/ruby/version.h: Talk about how JIT info is not in `ruby_description`. * test/-ext-/bug_reporter/test_bug_reporter.rb: Remove handling for crash description being different from `RUBY_DESCRIPTION`. * test/ruby/test_rubyoptions.rb: ditto Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org> Co-authored-by: Alan Wu <alanwu@ruby-lang.org>
If you run tests with RUN_OPTS=--mjit, the test fixes in #5872 don't work.
This was already done for MJIT due to ruby#5872
This was already done for MJIT due to ruby#5872
Issues fixed by this PR:
error.c
weren't getting the JIT informationI'm not intending to expose
rb_description()
as new public API - have I written the header correctly therefore?Was the macro
RUBY_DESCRIPTION_WITH
previously public API? Why and should I keep it as public?Motivation for this change is adding more option flags in the description string, such as which GC is in use.