-
Notifications
You must be signed in to change notification settings - Fork 11
Add remote symbolication support with build-id and PC offset #324
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
Changes from all commits
c52da1c
bd80f4c
04a7e9c
161ad44
55fbce3
0f3951b
dde78ee
a98db7a
8604a97
0fa6f7d
6924e55
ff8476f
fd63395
ef0b7e1
d63365e
1b7b1cc
e3d9a43
8d758bf
1215dc1
0e4235c
45d0122
3fa35e2
c90644d
74a9efe
0fe5b65
f4d2a8f
08d31e1
35ebb70
f193752
bb6ea57
8b80bf1
845a81a
05dedd5
d180ee3
f958fb0
b131a69
5a6c63d
527aba3
8164943
255201d
64b356e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,11 @@ | ||
| # build-and-summarize | ||
|
|
||
| Runs `./gradlew` with full output captured to a timestamped log, shows minimal live progress (task starts + final build/test summary), then asks the `gradle-logs-analyst` agent to produce structured artifacts from the log. | ||
| Execute the bash script `~/.claude/commands/build-and-summarize` with all provided arguments. | ||
|
|
||
| ## Usage | ||
| ```bash | ||
| ./.claude/commands/build-and-summarize [<gradle-args>...] | ||
| This script will: | ||
| - Run `./gradlew` with the specified arguments (defaults to 'build' if none provided) | ||
| - Capture full output to a timestamped log in `build/logs/` | ||
| - Show minimal live progress in the console | ||
| - Delegate to the `gradle-logs-analyst` agent for structured analysis | ||
|
|
||
| Pass through all arguments exactly as provided by the user. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,6 +37,11 @@ CodeCache::CodeCache(const char *name, short lib_index, | |
| _plt_size = 0; | ||
| _debug_symbols = false; | ||
|
|
||
| // Initialize build-id fields | ||
| _build_id = nullptr; | ||
| _build_id_len = 0; | ||
| _load_bias = 0; | ||
|
|
||
| memset(_imports, 0, sizeof(_imports)); | ||
| _imports_patchable = imports_patchable; | ||
|
|
||
|
|
@@ -48,16 +53,33 @@ CodeCache::CodeCache(const char *name, short lib_index, | |
| _blobs = new CodeBlob[_capacity]; | ||
| } | ||
|
|
||
| CodeCache::CodeCache(const CodeCache &other) { | ||
| void CodeCache::copyFrom(const CodeCache& other) { | ||
| _name = NativeFunc::create(other._name, -1); | ||
| _lib_index = other._lib_index; | ||
| _min_address = other._min_address; | ||
| _max_address = other._max_address; | ||
| _text_base = other._text_base; | ||
| _image_base = other._image_base; | ||
|
|
||
| _imports_patchable = other._imports_patchable; | ||
| _plt_offset = other._plt_offset; | ||
| _plt_size = other._plt_size; | ||
| _debug_symbols = other._debug_symbols; | ||
|
|
||
| // Copy build-id information | ||
| _build_id_len = other._build_id_len; | ||
| if (other._build_id != nullptr && other._build_id_len > 0) { | ||
| size_t hex_str_len = strlen(other._build_id); | ||
| _build_id = static_cast<char*>(malloc(hex_str_len + 1)); | ||
| if (_build_id != nullptr) { | ||
| strcpy(_build_id, other._build_id); | ||
| } | ||
| } else { | ||
| _build_id = nullptr; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That assignment is redundant, b/c build_id is initialized with nullptr. You could save the whole else-branch.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah. This is definitely not needed. |
||
| } | ||
| _load_bias = other._load_bias; | ||
|
|
||
| memset(_imports, 0, sizeof(_imports)); | ||
| _imports_patchable = other._imports_patchable; | ||
|
|
||
| _dwarf_table_length = other._dwarf_table_length; | ||
| _dwarf_table = new FrameDesc[_dwarf_table_length]; | ||
|
|
@@ -70,37 +92,23 @@ CodeCache::CodeCache(const CodeCache &other) { | |
| memcpy(_blobs, other._blobs, _count * sizeof(CodeBlob)); | ||
| } | ||
|
|
||
| CodeCache::CodeCache(const CodeCache &other) { | ||
| copyFrom(other); | ||
| } | ||
|
|
||
| CodeCache &CodeCache::operator=(const CodeCache &other) { | ||
| if (&other == this) { | ||
| return *this; | ||
| } else { | ||
| delete _name; | ||
| delete _dwarf_table; | ||
| delete _blobs; | ||
|
|
||
| _name = NativeFunc::create(other._name, -1); | ||
| _lib_index = other._lib_index; | ||
| _min_address = other._min_address; | ||
| _max_address = other._max_address; | ||
| _text_base = other._text_base; | ||
|
|
||
| _imports_patchable = other._imports_patchable; | ||
|
|
||
| _plt_offset = other._plt_offset; | ||
| _plt_size = other._plt_size; | ||
| } | ||
|
|
||
| _dwarf_table_length = other._dwarf_table_length; | ||
| _dwarf_table = new FrameDesc[_dwarf_table_length]; | ||
| memcpy(_dwarf_table, other._dwarf_table, | ||
| _dwarf_table_length * sizeof(FrameDesc)); | ||
| NativeFunc::destroy(_name); | ||
| delete[] _dwarf_table; | ||
| delete[] _blobs; | ||
| free(_build_id); | ||
|
|
||
| _capacity = other._capacity; | ||
| _count = other._count; | ||
| _blobs = new CodeBlob[_capacity]; | ||
| memcpy(_blobs, other._blobs, _count * sizeof(CodeBlob)); | ||
| copyFrom(other); | ||
|
|
||
| return *this; | ||
| } | ||
| return *this; | ||
| } | ||
|
|
||
| CodeCache::~CodeCache() { | ||
|
|
@@ -109,7 +117,8 @@ CodeCache::~CodeCache() { | |
| } | ||
| NativeFunc::destroy(_name); | ||
| delete[] _blobs; | ||
| delete _dwarf_table; | ||
| delete[] _dwarf_table; | ||
| free(_build_id); // Free build-id memory | ||
| } | ||
|
|
||
| void CodeCache::expand() { | ||
|
|
@@ -387,3 +396,24 @@ FrameDesc CodeCache::findFrameDesc(const void *pc) { | |
| return FrameDesc::default_frame; | ||
| } | ||
| } | ||
|
|
||
| void CodeCache::setBuildId(const char* build_id, size_t build_id_len) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Somehow I have the feeling here comes the same sequence of code, yet again (3rd time). Can this be unified (maybe the other 2 instances can be made to call this method)?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Created a shared function to copy the relevant parts. |
||
| // Free existing build-id if any | ||
| free(_build_id); | ||
| _build_id = nullptr; | ||
| _build_id_len = 0; | ||
|
|
||
| if (build_id != nullptr && build_id_len > 0) { | ||
| // build_id is a hex string, allocate based on actual string length | ||
| size_t hex_str_len = strlen(build_id); | ||
| _build_id = static_cast<char*>(malloc(hex_str_len + 1)); | ||
|
|
||
| if (_build_id != nullptr) { | ||
| // Copy the hex string | ||
| strcpy(_build_id, build_id); | ||
| // Store the original byte length (not hex string length) | ||
| _build_id_len = build_id_len; | ||
| } | ||
| } | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.