-
Notifications
You must be signed in to change notification settings - Fork 345
[lldb] Add parent address to Task synthetic provider #10936
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 1 commit
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 |
---|---|---|
|
@@ -734,6 +734,13 @@ namespace lldb_private { | |
namespace formatters { | ||
namespace swift { | ||
|
||
namespace { | ||
/// The size of Swift Tasks. Fragments are tail allocated. | ||
static constexpr size_t AsyncTaskSize = sizeof(::swift::AsyncTask); | ||
/// The offset of ChildFragment, which is the first fragment of an AsyncTask. | ||
static constexpr offset_t ChildFragmentOffset = AsyncTaskSize; | ||
} // namespace | ||
|
||
class EnumSyntheticFrontEnd : public SyntheticChildrenFrontEnd { | ||
public: | ||
EnumSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); | ||
|
@@ -806,6 +813,7 @@ class TaskSyntheticFrontEnd : public SyntheticChildrenFrontEnd { | |
"address", | ||
"id", | ||
"enqueuePriority", | ||
"parent", | ||
"children", | ||
|
||
// Children below this point are hidden. | ||
|
@@ -873,6 +881,33 @@ class TaskSyntheticFrontEnd : public SyntheticChildrenFrontEnd { | |
RETURN_CHILD(m_enqueue_priority_sp, enqueuePriority, priority_type); | ||
} | ||
case 3: { | ||
if (!m_parent_task_sp) { | ||
// TypeMangling for "Swift.UnsafeRawPointer" | ||
CompilerType raw_pointer_type = | ||
m_ts->GetTypeFromMangledTypename(ConstString("$sSVD")); | ||
|
||
addr_t parent_addr = 0; | ||
if (m_task_info.isChildTask) { | ||
if (auto process_sp = m_backend.GetProcessSP()) { | ||
Status status; | ||
// Read ChildFragment::Parent, the first field of the ChildFragment. | ||
parent_addr = process_sp->ReadPointerFromMemory( | ||
m_task_ptr + ChildFragmentOffset, status); | ||
if (status.Fail() || parent_addr == LLDB_INVALID_ADDRESS) | ||
parent_addr = 0; | ||
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. is this really what we want to do here? When the task has no parent, does the runtime write a 0 to its slot, or do we expect an error? If the runtime is explicitly writing a 0 and we don't expect the memory read to fail, I think we can just 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. For the case of a parent-less task, should we try to customize the formatter output to say something "root task" or "no parent", instead of 0s? I think 0s could give users the impression that the debugger failed to get the value 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.
A swift Task can have tail allocated "fragments", including a One way to model that is to make the existence of a
The We could put a string like "root task" into Task's summary formatter. In which case the On this subject, one of the questions I have for reviewers is the name of this member. I used 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.
I misspoke. A root task will of course have a 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. Adrian's suggestion is to have the parent's type be 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. yup that sounds good to me! |
||
} | ||
} | ||
addr_t value = parent_addr; | ||
DataExtractor data{reinterpret_cast<const void *>(&value), | ||
sizeof(value), endian::InlHostByteOrder(), | ||
sizeof(void *)}; | ||
m_parent_task_sp = ValueObject::CreateValueObjectFromData( | ||
"parent", data, m_backend.GetExecutionContextRef(), | ||
felipepiovezan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
raw_pointer_type); | ||
} | ||
return m_parent_task_sp; | ||
} | ||
case 4: { | ||
if (!m_child_tasks_sp) { | ||
using task_type = decltype(m_task_info.childTasks)::value_type; | ||
std::vector<task_type> tasks = m_task_info.childTasks; | ||
|
@@ -901,26 +936,26 @@ class TaskSyntheticFrontEnd : public SyntheticChildrenFrontEnd { | |
} | ||
return m_child_tasks_sp; | ||
} | ||
case 4: | ||
RETURN_CHILD(m_is_child_task_sp, isChildTask, bool_type); | ||
case 5: | ||
RETURN_CHILD(m_is_future_sp, isFuture, bool_type); | ||
RETURN_CHILD(m_is_child_task_sp, isChildTask, bool_type); | ||
case 6: | ||
RETURN_CHILD(m_is_group_child_task_sp, isGroupChildTask, bool_type); | ||
RETURN_CHILD(m_is_future_sp, isFuture, bool_type); | ||
case 7: | ||
RETURN_CHILD(m_is_async_let_task_sp, isAsyncLetTask, bool_type); | ||
RETURN_CHILD(m_is_group_child_task_sp, isGroupChildTask, bool_type); | ||
case 8: | ||
RETURN_CHILD(m_is_cancelled_sp, isCancelled, bool_type); | ||
RETURN_CHILD(m_is_async_let_task_sp, isAsyncLetTask, bool_type); | ||
case 9: | ||
RETURN_CHILD(m_is_cancelled_sp, isCancelled, bool_type); | ||
case 10: | ||
RETURN_CHILD(m_is_status_record_locked_sp, isStatusRecordLocked, | ||
bool_type); | ||
case 10: | ||
RETURN_CHILD(m_is_escalated_sp, isEscalated, bool_type); | ||
case 11: | ||
RETURN_CHILD(m_is_enqueued_sp, isEnqueued, bool_type); | ||
RETURN_CHILD(m_is_escalated_sp, isEscalated, bool_type); | ||
case 12: | ||
RETURN_CHILD(m_is_enqueued_sp, isEnqueued, bool_type); | ||
case 13: | ||
RETURN_CHILD(m_is_complete_sp, isComplete, bool_type); | ||
case 13: { | ||
case 14: { | ||
if (m_task_info.hasIsRunning) | ||
RETURN_CHILD(m_is_running_sp, isRunning, bool_type); | ||
return {}; | ||
|
@@ -953,8 +988,8 @@ class TaskSyntheticFrontEnd : public SyntheticChildrenFrontEnd { | |
m_is_child_task_sp, m_is_future_sp, m_is_group_child_task_sp, | ||
m_is_async_let_task_sp, m_is_cancelled_sp, | ||
m_is_status_record_locked_sp, m_is_escalated_sp, | ||
m_is_enqueued_sp, m_is_complete_sp, m_child_tasks_sp, | ||
m_is_running_sp}) | ||
m_is_enqueued_sp, m_is_complete_sp, m_parent_task_sp, | ||
m_child_tasks_sp, m_is_running_sp}) | ||
child.reset(); | ||
} | ||
} | ||
|
@@ -990,6 +1025,7 @@ class TaskSyntheticFrontEnd : public SyntheticChildrenFrontEnd { | |
ValueObjectSP m_is_escalated_sp; | ||
ValueObjectSP m_is_enqueued_sp; | ||
ValueObjectSP m_is_complete_sp; | ||
ValueObjectSP m_parent_task_sp; | ||
ValueObjectSP m_child_tasks_sp; | ||
ValueObjectSP m_is_running_sp; | ||
}; | ||
|
@@ -1280,8 +1316,6 @@ class TaskGroupSyntheticFrontEnd : public SyntheticChildrenFrontEnd { | |
bool operator==(const Task &other) const { return addr == other.addr; } | ||
bool operator!=(const Task &other) const { return !(*this == other); } | ||
|
||
static constexpr offset_t AsyncTaskSize = sizeof(::swift::AsyncTask); | ||
static constexpr offset_t ChildFragmentOffset = AsyncTaskSize; | ||
static constexpr offset_t NextChildOffset = ChildFragmentOffset + 0x8; | ||
|
||
Task getNextChild(Status &status) { | ||
|
Uh oh!
There was an error while loading. Please reload this page.