-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Fixes and improvements for debugging output #3469
Fixes and improvements for debugging output #3469
Conversation
- Declare parameters as well as local variables when emitting function debugging information - Add functions for forward declaration of types in LLVM >= 3.8 - Push LLVM version conditionals from debug.cr into di_builder.cr - Add spacing and comments in preprocessor directives in llvm_ext.cc to improve readability
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.
Thanks! Improvements to debug are always welcome. Could you refer to the LLVM documentation or expose a little bit the benefits. I don't know much of LLVM, and the documentation is sometimes a little abrupt to search.
@@ -86,8 +94,17 @@ lib LibLLVMExt | |||
align_in_bits : UInt64, | |||
name : LibC::Char*) : Metadata | |||
|
|||
{% if LibLLVM::IS_38 %} |
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 should be the other way around: if IS_35 or IS_36, because we also support 3.9 now, and I expect the functions to be available in 4.x too.
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.
You are absolutely right. It should be fixed in 0ca0868.
@@ -31,27 +31,37 @@ struct LLVM::DIBuilder | |||
|
|||
def create_function(scope, name, linkage_name, file, line, composite_type, is_local_to_unit, is_definition, | |||
scope_line, flags, is_optimized, func) | |||
LibLLVMExt.di_builder_create_function(self, scope, name, linkage_name, file, line, composite_type, is_local_to_unit, is_definition, | |||
scope_line, flags, is_optimized, func) | |||
{% if LibLLVM::IS_36 || LibLLVM::IS_35 %} |
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.
Thanks for hidding discrepancies into the LLVM module!
{% end %} | ||
builder.set_metadata(declare, @dbg_kind, builder.current_debug_location) | ||
{% end %} | ||
# TODO: This is redundant for LLVM >= 3.8, but currently we don't have access to builder from DIBuilder |
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.
Is it avoidable? Or could the method be a noop on 3.8+?
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.
Yep! Moved the logic to set the debug location to the C++ extension for LLVM <= 3.6 as well.
I also refactored these methods to avoid code repetition.
@@ -3,6 +3,8 @@ require "./codegen" | |||
module Crystal | |||
class CodeGenVisitor | |||
CRYSTAL_LANG_DEBUG_IDENTIFIER = 0x8002_u32 | |||
# TODO: for correctness, eventually this should come from the current LLVM context | |||
DBG_KIND = LibLLVM.get_md_kind_id("dbg", 3) |
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.
What about making it a method, so it would come from the current context?
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.
No longer relevant in 0ca0868, as I removed it altogether
- Refactor code to emit the `llvm.dbg.declare` instrinsic and reuse for both local variables and method arguments - Move debug location setting for debug declare instrinsic into C++ extension for LLVM <= 3.6 (functionality is built-in for LLVM >= 3.8) - Reformat `llvm_ext.cc` to conform to Crystal formatter
218f974
to
0ca0868
Compare
Agreed, the LLVM documentation is a bit hard to browse through. I'm a LLVM noob myself. Mostly, I've been referring to the source code directly, but the debugging chapter from the Kaleidoscope tutorial provided a nice introduction. Anyway, I updated the opening comment explaining some of the changes. |
Thank you! This looks all good to me, Travis is happy, and it should still compile against LLVM 3.6. @asterite what do you think? |
Looks really good to me! Merge? :-) (or rebase?) |
@ggiraldez we can't compile It happened in 0ca0868 |
llvm::DIBuilder.createReplaceableCompositeType
andllvm::DIBuilder.replaceTemporary
debug.cr
intodi_builder.cr
llvm_ext.cc
to improve readabilityEg. when compiling with debug info the following code
you can now display the values of the parameters
x
andy
, like so:(gdb) break my_add Breakpoint 1 at 0x1000041ca: file /Users/ggiraldez/ScratchPad/crystal-debug/foo.cr, line 1. (gdb) run ... Breakpoint 1, my_add (x=10, y=20) at /Users/ggiraldez/ScratchPad/crystal-debug/foo.cr:1 1 def my_add(x, y) (gdb) info locals z = 0 (gdb) info arg x = 10 y = 20 (gdb)
Regarding the new functions to handle forward declarations, using
LLVMTemporaryMDNode
andLLVMMetadataReplaceAllUsesWith
no longer works in LLVM 3.8. I run into this issue simply by compiling with LLVM 3.8.1 from Homebrew, then trying to compile this program with debug info:This crashed the compiler with a failed assertion:
Found the solution here: https://groups.google.com/d/msg/llvm-dev/9C3yuck4JZY/yDxxP9ypEwAJ