Initially I will send a patch to use Clang AST Context (before that I will push fix for improper derefrencer).
Then we can start implement proper Crystal Language Plugin for LLDB. I want to investigate GDB plugins and if it is possible to implement it with Python API (both LLDB and GDB use Python for scripting API, I used only LLDB for now as GDB does not work for me).
Interesting fact: 0x28 is somewhat reverse mirror for 0x8002 (if we remove zeroes in the middle), or simple flip of 8 from left to right., cyclic rotation to the left. ;)
I know the feeling! I had to do a lot of them during fixing the debug support as well. I still do even I have debug support now as I have t be sure that I am showing correct information.
At this moment I am fixing the debug line info as quite often debugger jumps some unexpected lines so to be able to finish debugger support PR I have to handle it as well.
I am just crying of happiness! Now even with line debug mismatch and some quirks for some of the debug types it is still waaaaaay to easy to debug the code.
@bcardiff I was able to figure out what was the issue with debug lines mismatch:
it was due how yield and blocks are inlined into the Def function. I had to modify fun_metadatas to incorporate stack of lexical blocks (with different files pointers) so it is able to find proper scope based on the context.fun and location.original_filename
Here is my version of it (in get_current_debug_scope):
array = fun_metadatas[context.fun]?
scope = nil
if array
array.each_with_index do |scope_pair, idx|
if scope_pair[0] == location.filename
scope = scope_pair[1]
Crystal.debug_log do
puts "get_current_debug_scope -> fun_metadatas[#{idx}]:\n\tloc: #{location}\n\tscope=#{dump_metadata(scope)}"
end
return scope
end
end
file, dir = file_and_dir(location.filename)
di_builder = di_builder()
file_scope = di_builder.create_file(file, dir)
scope = di_builder.create_lexical_block(fun_metadatas[context.fun][0][1], file_scope, location.line_number, location.column_number)
array << Tuple.new(location.original_filename || "??", scope)
Crystal.debug_log do
puts "get_current_debug_scope -> fun_metadatas[#{array.size}]:\n\tloc: #{location}\n\tscope=#{dump_metadata(scope)}\n\tscope=#{dump_metadata(file_scope)}"
end
end
scope
This approach (that I mentioned above) definitely fixed issue with wrong debug lines. So I will test more and will create a proper PR for this specific case.
But I would expect that the caller method will point to the yielding method source for the inlined instructions. Why the callee method needs to know about the lexical contexts?
There was a previous PR to add some testing for the debug information. If something like that can be included to ensure this feature will not break it would be awesome. It does not need to be fast or integrated in the compiler_spec. But it would need to be scriptable.
This is the way DWARF keeps information. One scope is connected to the file scope. if file is different than original one you have to create a new lexical scope that will point to new file and that scope will have a line numbers:
Ok. I pushed my fixes to my branch so now it shows block variables as well and it properly dives into the methods with blocks (before it was jumping randomly within the same file due to the file scope issue):
So if someone feels adventurous then just follow instructions in this thread above how to fix LLDB (and recompile it) or try it in GDB (I didnât tried yet as it does not work on my macOS) and you will be handsomely rewarded with debugging experience.
PS: There are still some glitches with debug info that needs to be ironed out but it is mainly useable.
@ComputerMage Regarding the yielding methods debug information, something I would expect to work is to treat them as inline method. At the end of the day, they are inlined during the codegen. With this approach the caller method will contain debug location for itself and the called one. Does this approach about using DW_AT_call_file and DW_AT_call_line make sense to you for this case?
Regarding the debug branch. Some minor feedback to match the code base:
Crystal.debug_log could be rewritten in a similar way as debug_codegen_log method.
All the new LibLLVMExt methods should have snake case name (I know they do in LLVM::DIBuilder)
The approach used by Rust has the advantage regarding the PR I mention before: It is easier to check manually some specific test case.
The effort put here is great and I really think we need some test cases to ensure we donât go backwards. (Iâm not asking for you to do it)
Many of the DW_LANG request delayed aprox month before been accepted.
I wonder what needs to happen after that so people have a compatible lldb version.
I will be very happy to work out the rest of the incorrect debug info bugs, since it enables using kcov for coverage reports of the stdlib spec suite, and makes stuff like coz.cr work correctly
This is a good idea, I will reimplement it and I will move the code next to it. Or I can even just reuse it as they are kinda similar.
Will add function alias to it.
I am investigating how are LLVM is generating those DIEs. Looks like I have to setup is_inlined flag on the lexical scope to make them generated.
We already can use identifier. As long as they not clashing with others, this is the reason why I skipped 0x27 as it may be picked up by either Kotlin Native or other contender.
What we need to do is just patch to LLDB to be accepted and probably the same for GDB
So we need to send the patch to both after the id is accepted, right?
And then we need to expect the users to update to the latest lldb/gdb version for that patch to be available, and that could take a while I guess. I am not sure if the ids can be updated somehow in current installations or we need to wait a release cycle. #DumbQuestionsSorry
No, we donât have to wait when lang id will be accepted. We claimed it first and most likely it will be awarded. If you can see above response to me from dwarfstd.org maintainer you will see that it is not necessary. Kotling guys are waiting for more than a year (almost two years) to accept it. It will be accepted when DWARF v6 will be published. So it is okay to use it as is as we publicly claimed that lang id.
I will need to send my other patch (for bug found by me) to LLDB guys as well to see immediate (not referenced) values. I didnât tested GDB for that yet but I will check it on my Linux instance.