summaryrefslogtreecommitdiffstats
path: root/lldb/tools/debugserver/source/MacOSX/Genealogy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/tools/debugserver/source/MacOSX/Genealogy.cpp')
-rw-r--r--lldb/tools/debugserver/source/MacOSX/Genealogy.cpp509
1 files changed, 264 insertions, 245 deletions
diff --git a/lldb/tools/debugserver/source/MacOSX/Genealogy.cpp b/lldb/tools/debugserver/source/MacOSX/Genealogy.cpp
index a5ee097aa2a..22ff52abaa4 100644
--- a/lldb/tools/debugserver/source/MacOSX/Genealogy.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/Genealogy.cpp
@@ -8,8 +8,8 @@
//===----------------------------------------------------------------------===//
#include <Availability.h>
-#include <string>
#include <dlfcn.h>
+#include <string>
#include <uuid/uuid.h>
#include "DNBDefs.h"
@@ -21,280 +21,299 @@
/// Constructor
//---------------------------
-Genealogy::Genealogy () :
- m_os_activity_diagnostic_for_pid (nullptr),
- m_os_activity_iterate_processes (nullptr),
- m_os_activity_iterate_breadcrumbs (nullptr),
- m_os_activity_iterate_messages (nullptr),
- m_os_activity_iterate_activities (nullptr),
- m_os_trace_get_type (nullptr),
- m_os_trace_copy_formatted_message (nullptr),
- m_os_activity_for_thread (nullptr),
- m_os_activity_for_task_thread (nullptr),
- m_thread_activities(),
- m_process_executable_infos(),
- m_diagnosticd_call_timed_out(false)
-{
- m_os_activity_diagnostic_for_pid = (bool (*)(pid_t, os_activity_t, uint32_t, os_diagnostic_block_t))dlsym (RTLD_DEFAULT, "os_activity_diagnostic_for_pid");
- m_os_activity_iterate_processes = (void (*)(os_activity_process_list_t, bool (^)(os_activity_process_t)))dlsym (RTLD_DEFAULT, "os_activity_iterate_processes");
- m_os_activity_iterate_breadcrumbs = (void (*)(os_activity_process_t, bool (^)(os_activity_breadcrumb_t))) dlsym (RTLD_DEFAULT, "os_activity_iterate_breadcrumbs");
- m_os_activity_iterate_messages = (void (*)(os_trace_message_list_t, os_activity_process_t, bool (^)(os_trace_message_t)))dlsym (RTLD_DEFAULT, "os_activity_iterate_messages");
- m_os_activity_iterate_activities = (void (*)(os_activity_list_t, os_activity_process_t, bool (^)(os_activity_entry_t)))dlsym (RTLD_DEFAULT, "os_activity_iterate_activities");
- m_os_trace_get_type = (uint8_t (*)(os_trace_message_t)) dlsym (RTLD_DEFAULT, "os_trace_get_type");
- m_os_trace_copy_formatted_message = (char *(*)(os_trace_message_t)) dlsym (RTLD_DEFAULT, "os_trace_copy_formatted_message");
- m_os_activity_for_thread = (os_activity_t (*)(os_activity_process_t, uint64_t)) dlsym (RTLD_DEFAULT, "os_activity_for_thread");
- m_os_activity_for_task_thread = (os_activity_t (*)(task_t, uint64_t)) dlsym (RTLD_DEFAULT, "os_activity_for_task_thread");
- m_os_activity_messages_for_thread = (os_trace_message_list_t (*) (os_activity_process_t process, os_activity_t activity, uint64_t thread_id)) dlsym (RTLD_DEFAULT, "os_activity_messages_for_thread");
+Genealogy::Genealogy()
+ : m_os_activity_diagnostic_for_pid(nullptr),
+ m_os_activity_iterate_processes(nullptr),
+ m_os_activity_iterate_breadcrumbs(nullptr),
+ m_os_activity_iterate_messages(nullptr),
+ m_os_activity_iterate_activities(nullptr), m_os_trace_get_type(nullptr),
+ m_os_trace_copy_formatted_message(nullptr),
+ m_os_activity_for_thread(nullptr), m_os_activity_for_task_thread(nullptr),
+ m_thread_activities(), m_process_executable_infos(),
+ m_diagnosticd_call_timed_out(false) {
+ m_os_activity_diagnostic_for_pid =
+ (bool (*)(pid_t, os_activity_t, uint32_t, os_diagnostic_block_t))dlsym(
+ RTLD_DEFAULT, "os_activity_diagnostic_for_pid");
+ m_os_activity_iterate_processes =
+ (void (*)(os_activity_process_list_t, bool (^)(os_activity_process_t)))
+ dlsym(RTLD_DEFAULT, "os_activity_iterate_processes");
+ m_os_activity_iterate_breadcrumbs =
+ (void (*)(os_activity_process_t, bool (^)(os_activity_breadcrumb_t)))
+ dlsym(RTLD_DEFAULT, "os_activity_iterate_breadcrumbs");
+ m_os_activity_iterate_messages = (void (*)(
+ os_trace_message_list_t, os_activity_process_t,
+ bool (^)(os_trace_message_t)))dlsym(RTLD_DEFAULT,
+ "os_activity_iterate_messages");
+ m_os_activity_iterate_activities = (void (*)(
+ os_activity_list_t, os_activity_process_t,
+ bool (^)(os_activity_entry_t)))dlsym(RTLD_DEFAULT,
+ "os_activity_iterate_activities");
+ m_os_trace_get_type =
+ (uint8_t(*)(os_trace_message_t))dlsym(RTLD_DEFAULT, "os_trace_get_type");
+ m_os_trace_copy_formatted_message = (char *(*)(os_trace_message_t))dlsym(
+ RTLD_DEFAULT, "os_trace_copy_formatted_message");
+ m_os_activity_for_thread =
+ (os_activity_t(*)(os_activity_process_t, uint64_t))dlsym(
+ RTLD_DEFAULT, "os_activity_for_thread");
+ m_os_activity_for_task_thread = (os_activity_t(*)(task_t, uint64_t))dlsym(
+ RTLD_DEFAULT, "os_activity_for_task_thread");
+ m_os_activity_messages_for_thread = (os_trace_message_list_t(*)(
+ os_activity_process_t process, os_activity_t activity,
+ uint64_t thread_id))dlsym(RTLD_DEFAULT,
+ "os_activity_messages_for_thread");
}
Genealogy::ThreadActivitySP
-Genealogy::GetGenealogyInfoForThread (pid_t pid, nub_thread_t tid, const MachThreadList &thread_list, task_t task, bool &timed_out)
-{
- ThreadActivitySP activity;
- //
- // if we've timed out trying to get the activities, don't try again at this process stop.
- // (else we'll need to hit the timeout for every thread we're asked about.)
- // We'll try again at the next public stop.
+Genealogy::GetGenealogyInfoForThread(pid_t pid, nub_thread_t tid,
+ const MachThreadList &thread_list,
+ task_t task, bool &timed_out) {
+ ThreadActivitySP activity;
+ //
+ // if we've timed out trying to get the activities, don't try again at this
+ // process stop.
+ // (else we'll need to hit the timeout for every thread we're asked about.)
+ // We'll try again at the next public stop.
- if (m_thread_activities.size() == 0 && m_diagnosticd_call_timed_out == false)
- {
- GetActivities(pid, thread_list, task);
- }
- std::map<nub_thread_t, ThreadActivitySP>::const_iterator search;
- search = m_thread_activities.find(tid);
- if (search != m_thread_activities.end())
- {
- activity = search->second;
- }
- timed_out = m_diagnosticd_call_timed_out;
- return activity;
+ if (m_thread_activities.size() == 0 &&
+ m_diagnosticd_call_timed_out == false) {
+ GetActivities(pid, thread_list, task);
+ }
+ std::map<nub_thread_t, ThreadActivitySP>::const_iterator search;
+ search = m_thread_activities.find(tid);
+ if (search != m_thread_activities.end()) {
+ activity = search->second;
+ }
+ timed_out = m_diagnosticd_call_timed_out;
+ return activity;
}
-void
-Genealogy::Clear()
-{
- m_thread_activities.clear();
- m_diagnosticd_call_timed_out = false;
+void Genealogy::Clear() {
+ m_thread_activities.clear();
+ m_diagnosticd_call_timed_out = false;
}
-void
-Genealogy::GetActivities(pid_t pid, const MachThreadList &thread_list, task_t task)
-{
- if (m_os_activity_diagnostic_for_pid != nullptr
- && m_os_activity_iterate_processes != nullptr
- && m_os_activity_iterate_breadcrumbs != nullptr
- && m_os_activity_iterate_messages != nullptr
- && m_os_activity_iterate_activities != nullptr
- && m_os_trace_get_type != nullptr
- && m_os_trace_copy_formatted_message != nullptr
- && (m_os_activity_for_thread != nullptr || m_os_activity_for_task_thread != nullptr)
- )
- {
- __block dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
- __block BreadcrumbList breadcrumbs;
- __block ActivityList activities;
- __block MessageList messages;
- __block std::map<nub_thread_t, uint64_t> thread_activity_mapping;
+void Genealogy::GetActivities(pid_t pid, const MachThreadList &thread_list,
+ task_t task) {
+ if (m_os_activity_diagnostic_for_pid != nullptr &&
+ m_os_activity_iterate_processes != nullptr &&
+ m_os_activity_iterate_breadcrumbs != nullptr &&
+ m_os_activity_iterate_messages != nullptr &&
+ m_os_activity_iterate_activities != nullptr &&
+ m_os_trace_get_type != nullptr &&
+ m_os_trace_copy_formatted_message != nullptr &&
+ (m_os_activity_for_thread != nullptr ||
+ m_os_activity_for_task_thread != nullptr)) {
+ __block dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
+ __block BreadcrumbList breadcrumbs;
+ __block ActivityList activities;
+ __block MessageList messages;
+ __block std::map<nub_thread_t, uint64_t> thread_activity_mapping;
- os_activity_diagnostic_flag_t flags = OS_ACTIVITY_DIAGNOSTIC_ALL_ACTIVITIES | OS_ACTIVITY_DIAGNOSTIC_PROCESS_ONLY;
- if (m_os_activity_diagnostic_for_pid (pid, 0, flags, ^(os_activity_process_list_t processes, int error)
- {
- if (error == 0)
- {
- m_os_activity_iterate_processes (processes, ^bool(os_activity_process_t process_info)
- {
- if (pid == process_info->pid)
- {
- // Collect all the Breadcrumbs
- m_os_activity_iterate_breadcrumbs (process_info, ^bool(os_activity_breadcrumb_t breadcrumb)
- {
- Breadcrumb bc;
- bc.breadcrumb_id = breadcrumb->breadcrumb_id;
- bc.activity_id = breadcrumb->activity_id;
- bc.timestamp = breadcrumb->timestamp;
- if (breadcrumb->name)
- bc.name = breadcrumb->name;
- breadcrumbs.push_back (bc);
- return true;
+ os_activity_diagnostic_flag_t flags =
+ OS_ACTIVITY_DIAGNOSTIC_ALL_ACTIVITIES |
+ OS_ACTIVITY_DIAGNOSTIC_PROCESS_ONLY;
+ if (m_os_activity_diagnostic_for_pid(
+ pid, 0, flags, ^(os_activity_process_list_t processes, int error) {
+ if (error == 0) {
+ m_os_activity_iterate_processes(processes, ^bool(
+ os_activity_process_t
+ process_info) {
+ if (pid == process_info->pid) {
+ // Collect all the Breadcrumbs
+ m_os_activity_iterate_breadcrumbs(
+ process_info,
+ ^bool(os_activity_breadcrumb_t breadcrumb) {
+ Breadcrumb bc;
+ bc.breadcrumb_id = breadcrumb->breadcrumb_id;
+ bc.activity_id = breadcrumb->activity_id;
+ bc.timestamp = breadcrumb->timestamp;
+ if (breadcrumb->name)
+ bc.name = breadcrumb->name;
+ breadcrumbs.push_back(bc);
+ return true;
});
- // Collect all the Activites
- m_os_activity_iterate_activities (process_info->activities, process_info, ^bool(os_activity_entry_t activity)
- {
- Activity ac;
- ac.activity_start = activity->activity_start;
- ac.activity_id = activity->activity_id;
- ac.parent_id = activity->parent_id;
- if (activity->activity_name)
- ac.activity_name = activity->activity_name;
- if (activity->reason)
- ac.reason = activity->reason;
- activities.push_back (ac);
- return true;
+ // Collect all the Activites
+ m_os_activity_iterate_activities(
+ process_info->activities, process_info,
+ ^bool(os_activity_entry_t activity) {
+ Activity ac;
+ ac.activity_start = activity->activity_start;
+ ac.activity_id = activity->activity_id;
+ ac.parent_id = activity->parent_id;
+ if (activity->activity_name)
+ ac.activity_name = activity->activity_name;
+ if (activity->reason)
+ ac.reason = activity->reason;
+ activities.push_back(ac);
+ return true;
});
-
- // Collect all the Messages -- messages not associated with any thread
- m_os_activity_iterate_messages (process_info->messages, process_info, ^bool(os_trace_message_t trace_msg)
- {
- Message msg;
- msg.timestamp = trace_msg->timestamp;
- msg.trace_id = trace_msg->trace_id;
- msg.thread = trace_msg->thread;
- msg.type = m_os_trace_get_type (trace_msg);
- msg.activity_id = 0;
- if (trace_msg->image_uuid && trace_msg->image_path)
- {
- ProcessExecutableInfoSP process_info_sp (new ProcessExecutableInfo());
- uuid_copy (process_info_sp->image_uuid, trace_msg->image_uuid);
- process_info_sp->image_path = trace_msg->image_path;
- msg.process_info_index = AddProcessExecutableInfo (process_info_sp);
- }
- const char *message_text = m_os_trace_copy_formatted_message (trace_msg);
- if (message_text)
- msg.message = message_text;
- messages.push_back (msg);
- return true;
+ // Collect all the Messages -- messages not associated with
+ // any thread
+ m_os_activity_iterate_messages(
+ process_info->messages, process_info,
+ ^bool(os_trace_message_t trace_msg) {
+ Message msg;
+ msg.timestamp = trace_msg->timestamp;
+ msg.trace_id = trace_msg->trace_id;
+ msg.thread = trace_msg->thread;
+ msg.type = m_os_trace_get_type(trace_msg);
+ msg.activity_id = 0;
+ if (trace_msg->image_uuid && trace_msg->image_path) {
+ ProcessExecutableInfoSP process_info_sp(
+ new ProcessExecutableInfo());
+ uuid_copy(process_info_sp->image_uuid,
+ trace_msg->image_uuid);
+ process_info_sp->image_path = trace_msg->image_path;
+ msg.process_info_index =
+ AddProcessExecutableInfo(process_info_sp);
+ }
+ const char *message_text =
+ m_os_trace_copy_formatted_message(trace_msg);
+ if (message_text)
+ msg.message = message_text;
+ messages.push_back(msg);
+ return true;
});
- // Discover which activities are said to be running on threads currently
- const nub_size_t num_threads = thread_list.NumThreads();
- for (nub_size_t i = 0; i < num_threads; ++i)
- {
- nub_thread_t thread_id = thread_list.ThreadIDAtIndex(i);
- os_activity_t act = 0;
- if (m_os_activity_for_task_thread != nullptr)
- {
- act = m_os_activity_for_task_thread (task, thread_id);
- }
- else if (m_os_activity_for_thread != nullptr)
- {
- act = m_os_activity_for_thread (process_info, thread_id);
- }
- if (act != 0)
- thread_activity_mapping[thread_id] = act;
- }
+ // Discover which activities are said to be running on
+ // threads currently
+ const nub_size_t num_threads = thread_list.NumThreads();
+ for (nub_size_t i = 0; i < num_threads; ++i) {
+ nub_thread_t thread_id = thread_list.ThreadIDAtIndex(i);
+ os_activity_t act = 0;
+ if (m_os_activity_for_task_thread != nullptr) {
+ act = m_os_activity_for_task_thread(task, thread_id);
+ } else if (m_os_activity_for_thread != nullptr) {
+ act = m_os_activity_for_thread(process_info, thread_id);
+ }
+ if (act != 0)
+ thread_activity_mapping[thread_id] = act;
+ }
- // Collect all Messages -- messages associated with a thread
+ // Collect all Messages -- messages associated with a thread
- // When there's no genealogy information, an early version of os_activity_messages_for_thread
- // can crash in rare circumstances. Check to see if this process has any activities before
- // making the call to get messages.
- if (process_info->activities != nullptr && thread_activity_mapping.size() > 0)
- {
- std::map<nub_thread_t, uint64_t>::const_iterator iter;
- for (iter = thread_activity_mapping.begin(); iter != thread_activity_mapping.end(); ++iter)
- {
- nub_thread_t thread_id = iter->first;
- os_activity_t act = iter->second;
- os_trace_message_list_t this_thread_messages = m_os_activity_messages_for_thread (process_info, act, thread_id);
- m_os_activity_iterate_messages (this_thread_messages, process_info, ^bool(os_trace_message_t trace_msg)
- {
- Message msg;
- msg.timestamp = trace_msg->timestamp;
- msg.trace_id = trace_msg->trace_id;
- msg.thread = trace_msg->thread;
- msg.type = m_os_trace_get_type (trace_msg);
- msg.activity_id = act;
- if (trace_msg->image_uuid && trace_msg->image_path)
- {
- ProcessExecutableInfoSP process_info_sp (new ProcessExecutableInfo());
- uuid_copy (process_info_sp->image_uuid, trace_msg->image_uuid);
- process_info_sp->image_path = trace_msg->image_path;
- msg.process_info_index = AddProcessExecutableInfo (process_info_sp);
- }
- const char *message_text = m_os_trace_copy_formatted_message (trace_msg);
- if (message_text)
- msg.message = message_text;
- messages.push_back (msg);
- return true;
- });
- }
- }
+ // When there's no genealogy information, an early version
+ // of os_activity_messages_for_thread
+ // can crash in rare circumstances. Check to see if this
+ // process has any activities before
+ // making the call to get messages.
+ if (process_info->activities != nullptr &&
+ thread_activity_mapping.size() > 0) {
+ std::map<nub_thread_t, uint64_t>::const_iterator iter;
+ for (iter = thread_activity_mapping.begin();
+ iter != thread_activity_mapping.end(); ++iter) {
+ nub_thread_t thread_id = iter->first;
+ os_activity_t act = iter->second;
+ os_trace_message_list_t this_thread_messages =
+ m_os_activity_messages_for_thread(process_info, act,
+ thread_id);
+ m_os_activity_iterate_messages(
+ this_thread_messages, process_info,
+ ^bool(os_trace_message_t trace_msg) {
+ Message msg;
+ msg.timestamp = trace_msg->timestamp;
+ msg.trace_id = trace_msg->trace_id;
+ msg.thread = trace_msg->thread;
+ msg.type = m_os_trace_get_type(trace_msg);
+ msg.activity_id = act;
+ if (trace_msg->image_uuid &&
+ trace_msg->image_path) {
+ ProcessExecutableInfoSP process_info_sp(
+ new ProcessExecutableInfo());
+ uuid_copy(process_info_sp->image_uuid,
+ trace_msg->image_uuid);
+ process_info_sp->image_path =
+ trace_msg->image_path;
+ msg.process_info_index =
+ AddProcessExecutableInfo(process_info_sp);
+ }
+ const char *message_text =
+ m_os_trace_copy_formatted_message(trace_msg);
+ if (message_text)
+ msg.message = message_text;
+ messages.push_back(msg);
+ return true;
+ });
+ }
}
- return true;
+ }
+ return true;
});
- }
- dispatch_semaphore_signal(semaphore);
- }) == true)
- {
- // Wait for the diagnosticd xpc calls to all finish up -- or half a second to elapse.
- dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC / 2);
- bool success = dispatch_semaphore_wait(semaphore, timeout) == 0;
- if (!success)
- {
- m_diagnosticd_call_timed_out = true;
- return;
- }
- }
+ }
+ dispatch_semaphore_signal(semaphore);
+ }) == true) {
+ // Wait for the diagnosticd xpc calls to all finish up -- or half a second
+ // to elapse.
+ dispatch_time_t timeout =
+ dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC / 2);
+ bool success = dispatch_semaphore_wait(semaphore, timeout) == 0;
+ if (!success) {
+ m_diagnosticd_call_timed_out = true;
+ return;
+ }
+ }
- // breadcrumbs, activities, and messages have all now been filled in.
+ // breadcrumbs, activities, and messages have all now been filled in.
- std::map<nub_thread_t, uint64_t>::const_iterator iter;
- for (iter = thread_activity_mapping.begin(); iter != thread_activity_mapping.end(); ++iter)
- {
- nub_thread_t thread_id = iter->first;
- uint64_t activity_id = iter->second;
- ActivityList::const_iterator activity_search;
- for (activity_search = activities.begin(); activity_search != activities.end(); ++activity_search)
- {
- if (activity_search->activity_id == activity_id)
- {
- ThreadActivitySP thread_activity_sp (new ThreadActivity());
- thread_activity_sp->current_activity = *activity_search;
-
- BreadcrumbList::const_iterator breadcrumb_search;
- for (breadcrumb_search = breadcrumbs.begin(); breadcrumb_search != breadcrumbs.end(); ++breadcrumb_search)
- {
- if (breadcrumb_search->activity_id == activity_id)
- {
- thread_activity_sp->breadcrumbs.push_back (*breadcrumb_search);
- }
- }
- MessageList::const_iterator message_search;
- for (message_search = messages.begin(); message_search != messages.end(); ++message_search)
- {
- if (message_search->thread == thread_id)
- {
- thread_activity_sp->messages.push_back (*message_search);
- }
- }
-
- m_thread_activities[thread_id] = thread_activity_sp;
- break;
- }
+ std::map<nub_thread_t, uint64_t>::const_iterator iter;
+ for (iter = thread_activity_mapping.begin();
+ iter != thread_activity_mapping.end(); ++iter) {
+ nub_thread_t thread_id = iter->first;
+ uint64_t activity_id = iter->second;
+ ActivityList::const_iterator activity_search;
+ for (activity_search = activities.begin();
+ activity_search != activities.end(); ++activity_search) {
+ if (activity_search->activity_id == activity_id) {
+ ThreadActivitySP thread_activity_sp(new ThreadActivity());
+ thread_activity_sp->current_activity = *activity_search;
+
+ BreadcrumbList::const_iterator breadcrumb_search;
+ for (breadcrumb_search = breadcrumbs.begin();
+ breadcrumb_search != breadcrumbs.end(); ++breadcrumb_search) {
+ if (breadcrumb_search->activity_id == activity_id) {
+ thread_activity_sp->breadcrumbs.push_back(*breadcrumb_search);
}
+ }
+ MessageList::const_iterator message_search;
+ for (message_search = messages.begin();
+ message_search != messages.end(); ++message_search) {
+ if (message_search->thread == thread_id) {
+ thread_activity_sp->messages.push_back(*message_search);
+ }
+ }
+
+ m_thread_activities[thread_id] = thread_activity_sp;
+ break;
}
+ }
}
+ }
}
uint32_t
-Genealogy::AddProcessExecutableInfo (ProcessExecutableInfoSP process_exe_info)
-{
- const uint32_t info_size = static_cast<uint32_t>(m_process_executable_infos.size());
- for (uint32_t idx = 0; idx < info_size; ++idx)
- {
- if (uuid_compare (m_process_executable_infos[idx]->image_uuid, process_exe_info->image_uuid) == 0)
- {
- return idx + 1;
- }
+Genealogy::AddProcessExecutableInfo(ProcessExecutableInfoSP process_exe_info) {
+ const uint32_t info_size =
+ static_cast<uint32_t>(m_process_executable_infos.size());
+ for (uint32_t idx = 0; idx < info_size; ++idx) {
+ if (uuid_compare(m_process_executable_infos[idx]->image_uuid,
+ process_exe_info->image_uuid) == 0) {
+ return idx + 1;
}
- m_process_executable_infos.push_back (process_exe_info);
- return info_size + 1;
+ }
+ m_process_executable_infos.push_back(process_exe_info);
+ return info_size + 1;
}
Genealogy::ProcessExecutableInfoSP
-Genealogy::GetProcessExecutableInfosAtIndex(size_t idx)
-{
- ProcessExecutableInfoSP info_sp;
- if (idx > 0)
- {
- idx--;
- if (idx <= m_process_executable_infos.size())
- {
- info_sp = m_process_executable_infos[idx];
- }
+Genealogy::GetProcessExecutableInfosAtIndex(size_t idx) {
+ ProcessExecutableInfoSP info_sp;
+ if (idx > 0) {
+ idx--;
+ if (idx <= m_process_executable_infos.size()) {
+ info_sp = m_process_executable_infos[idx];
}
- return info_sp;
+ }
+ return info_sp;
}
-
OpenPOWER on IntegriCloud