-
-
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
Improve debugging support #8538
Merged
Merged
Changes from 46 commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
6346c1c
Rudimentary debug support is here. It allows LLDB to show Crystal var…
401de7a
Rolled back enforced NoInline in debug mode.
b3105f4
Added comment to explain why we have to use C++ Language ID
574eb32
Added debug information for union and nullable types.
65cc438
Fixed some of the debug type glitches (MixedUnionType notoriously) as…
94a7e1c
Refactored debug information logging as per bcardiff comments
f0e82d4
Added array types debugging with DWARF support.
1f70c61
Some extra features was added to llvm module so now it is possible to…
9df1511
Added debug support for Tuples, NamedTuples, TypeDefs and partial sup…
82fd67e
Removed unnecessary debug logs and did some format tidy up.
75bf4c8
More of code tidy up.
3020b31
Moving LLVM functions to the class they belong to.
79de0c7
Neating up the code as per comments of reviewers.
c2a608c
Code cleanup as per Sija's comments.
0a75f31
Moved lldb crystal formatter into etc/lldb
436979e
Merge branch 'master' into debug
3be118a
Merge branch 'master' into debug
1576156
Rolled back previously set_current_debug_location as they are breaki…
5a60d9a
Fixes as per Sija's suggestions as well as fix for failed unit test d…
a163b74
Merge branch 'master' into debug
71f1dbc
autoformated source code
d779e17
Removed location code that is not needed and was redundant and also w…
599a555
Code clean up as per Sija's comments.
06f25e7
Typo fix! Thanks a lot, Sija!
84e8280
Some clean up to trigger the build to re-test Alpine Linux.
64e1316
Re-trigger build wth comment commit.
17a56a0
Fixed formatting issues (who knew that ### is not allowed! )
411f85a
initial refactor to use proper debug alloca
dc54cc8
fixing of alloca to be on alloca block
8c32552
formatted code
9785609
Merge branch 'master' of https://github.com/crystal-lang/crystal into…
910f742
Bug fixing for proper debug implementation. It should work properly n…
6efdf2f
Fix of code formatting.
a8bf28f
Code fixes and avoid generating debug info for naked functions
ab00367
Fixed function name typo that @Sija found
859734c
Addressed PR comments and refactored back to Type for debug_type_hash.
b01085a
changed the order of 'if' branch execution for setup_fun when --debug…
a8d0f41
Removed method attributes irrelevant for debugging as per @RX14
5229b4c
Refactored code as per suggestions from @asterlite and @Sija
7e78afc
Code refactoring as per @Sija suggestions
ce1d00c
Removed all unused methods that were implemented during debug support…
f81e506
Merge branch 'master' of https://github.com/crystal-lang/crystal into…
7324863
Merge branch 'master' into debug
bcardiff 3291ec8
Initial debug specs
bcardiff 4024e52
Merge commit '3291ec8533c4bb505ac122c9e6bd3e17b6502032' into debug
3811814
Cherrypicked debug driver from @bcardiff
83d3e8c
Merge branch 'master' of https://github.com/crystal-lang/crystal into…
c0e2417
Merge branch 'master' of https://github.com/crystal-lang/crystal into…
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import lldb | ||
|
||
class CrystalArraySyntheticProvider: | ||
def __init__(self, valobj, internal_dict): | ||
self.valobj = valobj | ||
self.buffer = None | ||
self.size = 0 | ||
|
||
def update(self): | ||
if self.valobj.type.is_pointer: | ||
self.valobj = self.valobj.Dereference() | ||
self.size = int(self.valobj.child[0].value) | ||
self.type = self.valobj.type | ||
self.buffer = self.valobj.child[2] | ||
|
||
def num_children(self): | ||
size = 0 if self.size is None else self.size | ||
return size | ||
|
||
def get_child_index(self, name): | ||
try: | ||
return int(name.lstrip('[').rstrip(']')) | ||
except: | ||
return -1 | ||
|
||
def get_child_at_index(self,index): | ||
if index >= self.size: | ||
return None | ||
try: | ||
elementType = self.buffer.type.GetPointeeType() | ||
offset = elementType.size * index | ||
return self.buffer.CreateChildAtOffset('[' + str(index) + ']', offset, elementType) | ||
except Exception as e: | ||
print('Got exception %s' % (str(e))) | ||
return None | ||
|
||
def findType(name, module): | ||
cachedTypes = module.GetTypes() | ||
for idx in range(cachedTypes.GetSize()): | ||
type = cachedTypes.GetTypeAtIndex(idx) | ||
if type.name == name: | ||
return type | ||
return None | ||
|
||
|
||
def CrystalString_SummaryProvider(value, dict): | ||
error = lldb.SBError() | ||
if value.TypeIsPointerType(): | ||
value = value.Dereference() | ||
process = value.GetTarget().GetProcess() | ||
byteSize = int(value.child[0].value) | ||
len = int(value.child[1].value) | ||
len = byteSize or len | ||
strAddr = value.child[2].load_addr | ||
val = process.ReadCStringFromMemory(strAddr, len + 1, error) | ||
return '"%s"' % val | ||
|
||
|
||
def __lldb_init_module(debugger, dict): | ||
debugger.HandleCommand('type synthetic add -l crystal_formatters.CrystalArraySyntheticProvider -x "^Array\(.+\)(\s*\**)?" -w Crystal') | ||
debugger.HandleCommand('type summary add -F crystal_formatters.CrystalString_SummaryProvider -x "^(String|\(String \| Nil\))(\s*\**)?$" -w Crystal') | ||
debugger.HandleCommand('type category enable Crystal') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
def each_line1(file) | ||
File.read_lines(file).each_with_index do |line, index0| | ||
yield line, index0 + 1 | ||
end | ||
end | ||
|
||
repo_base_dir = "#{__DIR__}/../../" | ||
tmp_build_dir = File.join(repo_base_dir, ".build") | ||
Dir.mkdir_p(tmp_build_dir) | ||
|
||
input = ARGV[0] | ||
|
||
bin = File.join(tmp_build_dir, "debug_test_case") | ||
debugger_script = File.join(tmp_build_dir, "./debugger.script") | ||
|
||
`#{repo_base_dir}/bin/crystal build --debug #{input} -o #{bin}` | ||
|
||
File.open(debugger_script, "w") do |script| | ||
lldb_crystal_formatters = File.expand_path(File.join(repo_base_dir, "etc", "lldb", "crystal_formatters.py")) | ||
script.puts "version" | ||
script.puts "command script import #{lldb_crystal_formatters}" | ||
|
||
each_line1(input) do |line, line_number| | ||
if line.match(/# break\b/) | ||
script.puts "breakpoint set --file #{input} --line #{line_number}" | ||
end | ||
end | ||
|
||
script.puts "run" | ||
|
||
each_line1(input) do |line| | ||
if md = line.match(/# lldb-command: (.*)/) | ||
script.puts md[1] | ||
end | ||
end | ||
end | ||
|
||
session_output_dir = File.join(repo_base_dir, "tmp", "debug") | ||
Dir.mkdir_p(session_output_dir) | ||
|
||
session_log = File.join(session_output_dir, File.basename(input, File.extname(input)) + ".lldb-session") | ||
session_assert = File.join(session_output_dir, File.basename(input, File.extname(input)) + ".lldb-assert") | ||
|
||
File.open(session_assert, "w") do |assert| | ||
each_line1(input) do |line| | ||
if md = line.match(/# lldb-command: (.*)/) | ||
assert.puts "CHECK: (lldb) #{md[1]}" | ||
elsif md = line.match(/# lldb-check: (.*)/) | ||
assert.puts "CHECK-NEXT: #{md[1]}" | ||
end | ||
end | ||
end | ||
|
||
`/usr/bin/lldb -b --source #{debugger_script} #{bin} > #{session_log}` | ||
|
||
`FileCheck #{session_assert} < #{session_log}` | ||
|
||
exit $?.exit_code |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# NOTE: breakpoint on line 1 + next does not work | ||
a = "hello world" # break | ||
# lldb-command: n | ||
# lldb-command: print a | ||
# lldb-check: (String *) $0 = {{0x[0-9a-f]+}} "hello world" | ||
b = 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#!/bin/sh | ||
|
||
# This file can be executed from the root of the working copy | ||
# | ||
# $ ./spec/debug/test.sh | ||
# | ||
# It will use the ./spec/debug/driver.cr program to execute | ||
# the files explicitly listed at the end of this file. | ||
# | ||
# Those files have magic comments to build a script for an lldb session | ||
# and a FileCheck file with assertions over that session. | ||
# | ||
# In ./tmp/debug you can find a dump of the session and the assertion file. | ||
# | ||
# The magic comments interpreted by the driver are: | ||
# | ||
# * # break | ||
# * # lldb-command: | ||
# * # lldb-check: | ||
# | ||
|
||
set -euo pipefail | ||
|
||
SCRIPT_PATH="$(realpath "$0")" | ||
SCRIPT_ROOT="$(dirname "$SCRIPT_PATH")" | ||
|
||
BUILD_DIR=$SCRIPT_ROOT/../../.build | ||
crystal=$SCRIPT_ROOT/../../bin/crystal | ||
driver=$BUILD_DIR/debug_driver | ||
mkdir -p $BUILD_DIR | ||
$crystal build $SCRIPT_ROOT/driver.cr -o $driver | ||
|
||
$driver $SCRIPT_ROOT/top_level.cr | ||
$driver $SCRIPT_ROOT/strings.cr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# NOTE: breakpoint on line 1 + next does not work | ||
a = 42 # break | ||
# lldb-command: print a | ||
# lldb-check: (int) $0 = 0 | ||
# lldb-command: n | ||
# lldb-command: print a | ||
# lldb-check: (int) $1 = 42 | ||
b = 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Other invocations of
declare_variable
occur only ifif @debug.variables?
. With than in mind there are some refactor that can be applied since that method now does a noop unless@debug.variables?