summaryrefslogtreecommitdiffstats
path: root/lldb/tools
diff options
context:
space:
mode:
authorHan Ming Ong <hanming@apple.com>2013-03-04 21:25:51 +0000
committerHan Ming Ong <hanming@apple.com>2013-03-04 21:25:51 +0000
commit8764fe7d9aa133b037528f1d118e6a6259f2f0ee (patch)
tree46526a13451d1492f3b4abf27b1cf3def48df723 /lldb/tools
parent2a513e8218e7b5a9ee865d5ab09c892dce3944fc (diff)
downloadbcm5719-llvm-8764fe7d9aa133b037528f1d118e6a6259f2f0ee.tar.gz
bcm5719-llvm-8764fe7d9aa133b037528f1d118e6a6259f2f0ee.zip
<rdar://problem/13338758>
Make it configurable what to profile. For Mac, we don't use the dirty page size yet and hence there is no need to gather that. This should be way better in not draining the battery since we are operating between 0% to 0.1% on the Mac after this change. llvm-svn: 176451
Diffstat (limited to 'lldb/tools')
-rw-r--r--lldb/tools/debugserver/source/DNB.cpp8
-rw-r--r--lldb/tools/debugserver/source/DNB.h4
-rw-r--r--lldb/tools/debugserver/source/DNBDefs.h17
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachProcess.cpp5
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachProcess.h6
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachTask.cpp177
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachTask.h3
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp32
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachVMMemory.h2
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.cpp42
10 files changed, 196 insertions, 100 deletions
diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp
index 36508e986e7..ed19b097327 100644
--- a/lldb/tools/debugserver/source/DNB.cpp
+++ b/lldb/tools/debugserver/source/DNB.cpp
@@ -1220,22 +1220,22 @@ DNBProcessMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, DNBRegionInfo *r
}
std::string
-DNBProcessGetProfileData (nub_process_t pid)
+DNBProcessGetProfileData (nub_process_t pid, DNBProfileDataScanType scanType)
{
MachProcessSP procSP;
if (GetProcessSP (pid, procSP))
- return procSP->Task().GetProfileData();
+ return procSP->Task().GetProfileData(scanType);
return std::string("");
}
nub_bool_t
-DNBProcessSetEnableAsyncProfiling (nub_process_t pid, nub_bool_t enable, uint64_t interval_usec)
+DNBProcessSetEnableAsyncProfiling (nub_process_t pid, nub_bool_t enable, uint64_t interval_usec, DNBProfileDataScanType scan_type)
{
MachProcessSP procSP;
if (GetProcessSP (pid, procSP))
{
- procSP->SetEnableAsyncProfiling(enable, interval_usec);
+ procSP->SetEnableAsyncProfiling(enable, interval_usec, scan_type);
return true;
}
diff --git a/lldb/tools/debugserver/source/DNB.h b/lldb/tools/debugserver/source/DNB.h
index 2e14387cbcc..83366dbf999 100644
--- a/lldb/tools/debugserver/source/DNB.h
+++ b/lldb/tools/debugserver/source/DNB.h
@@ -63,8 +63,8 @@ nub_size_t DNBProcessMemoryWrite (nub_process_t pid, nub_addr_t addr, nub
nub_addr_t DNBProcessMemoryAllocate (nub_process_t pid, nub_size_t size, uint32_t permissions) DNB_EXPORT;
nub_bool_t DNBProcessMemoryDeallocate (nub_process_t pid, nub_addr_t addr) DNB_EXPORT;
int DNBProcessMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, DNBRegionInfo *region_info) DNB_EXPORT;
-std::string DNBProcessGetProfileData (nub_process_t pid) DNB_EXPORT;
-nub_bool_t DNBProcessSetEnableAsyncProfiling (nub_process_t pid, nub_bool_t enable, uint64_t interval_usec) DNB_EXPORT;
+std::string DNBProcessGetProfileData (nub_process_t pid, DNBProfileDataScanType scanType) DNB_EXPORT;
+nub_bool_t DNBProcessSetEnableAsyncProfiling (nub_process_t pid, nub_bool_t enable, uint64_t interval_usec, DNBProfileDataScanType scan_type) DNB_EXPORT;
//----------------------------------------------------------------------
// Process status
diff --git a/lldb/tools/debugserver/source/DNBDefs.h b/lldb/tools/debugserver/source/DNBDefs.h
index 47a2a866964..de8b99a2f04 100644
--- a/lldb/tools/debugserver/source/DNBDefs.h
+++ b/lldb/tools/debugserver/source/DNBDefs.h
@@ -358,6 +358,23 @@ struct DNBRegionInfo
uint32_t permissions;
};
+enum DNBProfileDataScanType
+{
+ eProfileHostCPU = (1 << 0),
+ eProfileCPU = (1 << 1),
+
+ eProfileThreadsCPU = (1 << 2), // By default excludes eProfileThreadName and eProfileQueueName.
+ eProfileThreadName = (1 << 3), // Assume eProfileThreadsCPU, get thread name as well.
+ eProfileQueueName = (1 << 4), // Assume eProfileThreadsCPU, get queue name as well.
+
+ eProfileHostMemory = (1 << 5),
+
+ eProfileMemory = (1 << 6), // By default, excludes eProfileMemoryDirtyPage.
+ eProfileMemoryDirtyPage = (1 << 7), // Assume eProfileMemory, get Dirty Page size as well.
+
+ eProfileAll = 0xffffffff
+};
+
typedef nub_bool_t (*DNBCallbackBreakpointHit)(nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *baton);
typedef nub_addr_t (*DNBCallbackNameToAddress)(nub_process_t pid, const char *name, const char *shlib_regex, void *baton);
typedef nub_size_t (*DNBCallbackCopyExecutableImageInfos)(nub_process_t pid, struct DNBExecutableImageInfo **image_infos, nub_bool_t only_changed, void *baton);
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
index 33847ebec85..0f7250a8b8f 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
@@ -315,10 +315,11 @@ MachProcess::StartSTDIOThread()
}
void
-MachProcess::SetEnableAsyncProfiling(bool enable, uint64_t interval_usec)
+MachProcess::SetEnableAsyncProfiling(bool enable, uint64_t interval_usec, DNBProfileDataScanType scan_type)
{
m_profile_enabled = enable;
m_profile_interval_usec = interval_usec;
+ m_profile_scan_type = scan_type;
if (m_profile_enabled && (m_profile_thread == NULL))
{
@@ -1411,7 +1412,7 @@ MachProcess::ProfileThread(void *arg)
nub_state_t state = proc->GetState();
if (state == eStateRunning)
{
- std::string data = proc->Task().GetProfileData();
+ std::string data = proc->Task().GetProfileData(proc->GetProfileScanType());
if (!data.empty())
{
proc->SignalAsyncProfileData(data.c_str());
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
index f4529364909..542c3dbc93a 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
@@ -148,7 +148,7 @@ public:
//----------------------------------------------------------------------
// Profile functions
//----------------------------------------------------------------------
- void SetEnableAsyncProfiling (bool enable, uint64_t internal_usec);
+ void SetEnableAsyncProfiling (bool enable, uint64_t internal_usec, DNBProfileDataScanType scan_type);
bool IsProfilingEnabled () { return m_profile_enabled; }
uint64_t ProfileInterval () { return m_profile_interval_usec; }
bool StartProfileThread ();
@@ -250,6 +250,9 @@ public:
}
bool ProcessUsingSpringBoard() const { return (m_flags & eMachProcessFlagsUsingSBS) != 0; }
+
+ DNBProfileDataScanType GetProfileScanType () { return m_profile_scan_type; }
+
private:
enum
{
@@ -282,6 +285,7 @@ private:
bool m_profile_enabled; // A flag to indicate if profiling is enabled
uint64_t m_profile_interval_usec; // If enable, the profiling interval in microseconds
+ DNBProfileDataScanType m_profile_scan_type; // Indicates what needs to be profiled
pthread_t m_profile_thread; // Thread ID for the thread that profiles the inferior
PThreadMutex m_profile_data_mutex; // Multithreaded protection for profile info data
std::vector<std::string> m_profile_data; // Profile data, must be protected by m_profile_data_mutex
diff --git a/lldb/tools/debugserver/source/MacOSX/MachTask.cpp b/lldb/tools/debugserver/source/MacOSX/MachTask.cpp
index 785f1e74b92..21c10dde077 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachTask.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachTask.cpp
@@ -233,7 +233,7 @@ MachTask::GetMemoryRegionInfo (nub_addr_t addr, DNBRegionInfo *region_info)
} while (0)
// We should consider moving this into each MacThread.
-static void get_threads_profile_data(task_t task, nub_process_t pid, std::vector<uint64_t> &threads_id, std::vector<std::string> &threads_name, std::vector<uint64_t> &threads_used_usec)
+static void get_threads_profile_data(DNBProfileDataScanType scanType, task_t task, nub_process_t pid, std::vector<uint64_t> &threads_id, std::vector<std::string> &threads_name, std::vector<uint64_t> &threads_used_usec)
{
kern_return_t kr;
thread_act_array_t threads;
@@ -243,7 +243,8 @@ static void get_threads_profile_data(task_t task, nub_process_t pid, std::vector
if (kr != KERN_SUCCESS)
return;
- for (int i = 0; i < tcnt; i++) {
+ for (int i = 0; i < tcnt; i++)
+ {
thread_identifier_info_data_t identifier_info;
mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
kr = ::thread_info(threads[i], THREAD_IDENTIFIER_INFO, (thread_info_t)&identifier_info, &count);
@@ -254,22 +255,26 @@ static void get_threads_profile_data(task_t task, nub_process_t pid, std::vector
kr = ::thread_info(threads[i], THREAD_BASIC_INFO, (thread_info_t)&basic_info, &count);
if (kr != KERN_SUCCESS) continue;
- if ((basic_info.flags & TH_FLAGS_IDLE) == 0) {
+ if ((basic_info.flags & TH_FLAGS_IDLE) == 0)
+ {
nub_thread_t tid = MachThread::GetGloballyUniqueThreadIDForMachPortID (threads[i]);
-
threads_id.push_back(tid);
- if (identifier_info.thread_handle != 0) {
+ if ((scanType & eProfileThreadName) && (identifier_info.thread_handle != 0))
+ {
struct proc_threadinfo proc_threadinfo;
int len = ::proc_pidinfo(pid, PROC_PIDTHREADINFO, identifier_info.thread_handle, &proc_threadinfo, PROC_PIDTHREADINFO_SIZE);
- if (len && proc_threadinfo.pth_name[0]) {
+ if (len && proc_threadinfo.pth_name[0])
+ {
threads_name.push_back(proc_threadinfo.pth_name);
}
- else {
+ else
+ {
threads_name.push_back("");
}
}
- else {
+ else
+ {
threads_name.push_back("");
}
struct timeval tv;
@@ -289,26 +294,29 @@ static void get_threads_profile_data(task_t task, nub_process_t pid, std::vector
#define RAW_HEXBASE std::setfill('0') << std::hex << std::right
#define DECIMAL std::dec << std::setfill(' ')
std::string
-MachTask::GetProfileData ()
+MachTask::GetProfileData (DNBProfileDataScanType scanType)
{
std::string result;
static int32_t numCPU = -1;
- int32_t mib[] = {CTL_HW, HW_AVAILCPU};
- size_t len = sizeof(numCPU);
- if (numCPU == -1)
+ struct host_cpu_load_info host_info;
+ if (scanType & eProfileHostCPU)
{
- if (sysctl(mib, sizeof(mib) / sizeof(int32_t), &numCPU, &len, NULL, 0) != 0)
+ int32_t mib[] = {CTL_HW, HW_AVAILCPU};
+ size_t len = sizeof(numCPU);
+ if (numCPU == -1)
+ {
+ if (sysctl(mib, sizeof(mib) / sizeof(int32_t), &numCPU, &len, NULL, 0) != 0)
+ return result;
+ }
+
+ mach_port_t localHost = mach_host_self();
+ mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
+ kern_return_t kr = host_statistics(localHost, HOST_CPU_LOAD_INFO, (host_info_t)&host_info, &count);
+ if (kr != KERN_SUCCESS)
return result;
}
- mach_port_t localHost = mach_host_self();
- struct host_cpu_load_info host_info;
- mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
- kern_return_t kr = host_statistics(localHost, HOST_CPU_LOAD_INFO, (host_info_t)&host_info, &count);
- if (kr != KERN_SUCCESS)
- return result;
-
task_t task = TaskPort();
if (task == TASK_NULL)
return result;
@@ -322,24 +330,31 @@ MachTask::GetProfileData ()
uint64_t elapsed_usec = 0;
uint64_t task_used_usec = 0;
+ if (scanType & eProfileCPU)
+ {
+ // Get current used time.
+ struct timeval current_used_time;
+ struct timeval tv;
+ TIME_VALUE_TO_TIMEVAL(&task_info.user_time, &current_used_time);
+ TIME_VALUE_TO_TIMEVAL(&task_info.system_time, &tv);
+ timeradd(&current_used_time, &tv, &current_used_time);
+ task_used_usec = current_used_time.tv_sec * 1000000ULL + current_used_time.tv_usec;
+
+ struct timeval current_elapsed_time;
+ int res = gettimeofday(&current_elapsed_time, NULL);
+ if (res == 0)
+ {
+ elapsed_usec = current_elapsed_time.tv_sec * 1000000ULL + current_elapsed_time.tv_usec;
+ }
+ }
+
std::vector<uint64_t> threads_id;
std::vector<std::string> threads_name;
std::vector<uint64_t> threads_used_usec;
-
- // Get current used time.
- struct timeval current_used_time;
- struct timeval tv;
- TIME_VALUE_TO_TIMEVAL(&task_info.user_time, &current_used_time);
- TIME_VALUE_TO_TIMEVAL(&task_info.system_time, &tv);
- timeradd(&current_used_time, &tv, &current_used_time);
- task_used_usec = current_used_time.tv_sec * 1000000ULL + current_used_time.tv_usec;
- get_threads_profile_data(task, m_process->ProcessID(), threads_id, threads_name, threads_used_usec);
-
- struct timeval current_elapsed_time;
- int res = gettimeofday(&current_elapsed_time, NULL);
- if (res == 0)
+
+ if (scanType & eProfileThreadsCPU)
{
- elapsed_usec = current_elapsed_time.tv_sec * 1000000ULL + current_elapsed_time.tv_usec;
+ get_threads_profile_data(scanType, task, m_process->ProcessID(), threads_id, threads_name, threads_used_usec);
}
struct vm_statistics vm_stats;
@@ -349,53 +364,75 @@ MachTask::GetProfileData ()
mach_vm_size_t vprvt = 0;
mach_vm_size_t vsize = 0;
mach_vm_size_t dirty_size = 0;
- if (m_vm_memory.GetMemoryProfile(task, task_info, m_process->GetCPUType(), m_process->ProcessID(), vm_stats, physical_memory, rprvt, rsize, vprvt, vsize, dirty_size))
+ if (m_vm_memory.GetMemoryProfile(scanType, task, task_info, m_process->GetCPUType(), m_process->ProcessID(), vm_stats, physical_memory, rprvt, rsize, vprvt, vsize, dirty_size))
{
std::ostringstream profile_data_stream;
- profile_data_stream << "num_cpu:" << numCPU << ';';
- profile_data_stream << "host_user_ticks:" << host_info.cpu_ticks[CPU_STATE_USER] << ';';
- profile_data_stream << "host_sys_ticks:" << host_info.cpu_ticks[CPU_STATE_SYSTEM] << ';';
- profile_data_stream << "host_idle_ticks:" << host_info.cpu_ticks[CPU_STATE_IDLE] << ';';
+ if (scanType & eProfileHostCPU)
+ {
+ profile_data_stream << "num_cpu:" << numCPU << ';';
+ profile_data_stream << "host_user_ticks:" << host_info.cpu_ticks[CPU_STATE_USER] << ';';
+ profile_data_stream << "host_sys_ticks:" << host_info.cpu_ticks[CPU_STATE_SYSTEM] << ';';
+ profile_data_stream << "host_idle_ticks:" << host_info.cpu_ticks[CPU_STATE_IDLE] << ';';
+ }
- profile_data_stream << "elapsed_usec:" << elapsed_usec << ';';
- profile_data_stream << "task_used_usec:" << task_used_usec << ';';
+ if (scanType & eProfileCPU)
+ {
+ profile_data_stream << "elapsed_usec:" << elapsed_usec << ';';
+ profile_data_stream << "task_used_usec:" << task_used_usec << ';';
+ }
- int num_threads = threads_id.size();
- for (int i=0; i<num_threads; i++) {
- profile_data_stream << "thread_used_id:" << std::hex << threads_id[i] << std::dec << ';';
- profile_data_stream << "thread_used_usec:" << threads_used_usec[i] << ';';
-
- profile_data_stream << "thread_used_name:";
- int len = threads_name[i].size();
- if (len) {
- const char *thread_name = threads_name[i].c_str();
- // Make sure that thread name doesn't interfere with our delimiter.
- profile_data_stream << RAW_HEXBASE << std::setw(2);
- const uint8_t *ubuf8 = (const uint8_t *)(thread_name);
- for (int j=0; j<len; j++)
+ if (scanType & eProfileThreadsCPU)
+ {
+ int num_threads = threads_id.size();
+ for (int i=0; i<num_threads; i++)
+ {
+ profile_data_stream << "thread_used_id:" << std::hex << threads_id[i] << std::dec << ';';
+ profile_data_stream << "thread_used_usec:" << threads_used_usec[i] << ';';
+
+ if (scanType & eProfileThreadName)
{
- profile_data_stream << (uint32_t)(ubuf8[j]);
+ profile_data_stream << "thread_used_name:";
+ int len = threads_name[i].size();
+ if (len)
+ {
+ const char *thread_name = threads_name[i].c_str();
+ // Make sure that thread name doesn't interfere with our delimiter.
+ profile_data_stream << RAW_HEXBASE << std::setw(2);
+ const uint8_t *ubuf8 = (const uint8_t *)(thread_name);
+ for (int j=0; j<len; j++)
+ {
+ profile_data_stream << (uint32_t)(ubuf8[j]);
+ }
+ // Reset back to DECIMAL.
+ profile_data_stream << DECIMAL;
+ }
+ profile_data_stream << ';';
}
- // Reset back to DECIMAL.
- profile_data_stream << DECIMAL;
}
- profile_data_stream << ';';
}
- profile_data_stream << "wired:" << vm_stats.wire_count * vm_page_size << ';';
- profile_data_stream << "active:" << vm_stats.active_count * vm_page_size << ';';
- profile_data_stream << "inactive:" << vm_stats.inactive_count * vm_page_size << ';';
- uint64_t total_used_count = vm_stats.wire_count + vm_stats.inactive_count + vm_stats.active_count;
- profile_data_stream << "used:" << total_used_count * vm_page_size << ';';
- profile_data_stream << "free:" << vm_stats.free_count * vm_page_size << ';';
- profile_data_stream << "total:" << physical_memory << ';';
+ if (scanType & eProfileHostMemory)
+ profile_data_stream << "total:" << physical_memory << ';';
+
+ if (scanType & eProfileMemory)
+ {
+ profile_data_stream << "wired:" << vm_stats.wire_count * vm_page_size << ';';
+ profile_data_stream << "active:" << vm_stats.active_count * vm_page_size << ';';
+ profile_data_stream << "inactive:" << vm_stats.inactive_count * vm_page_size << ';';
+ uint64_t total_used_count = vm_stats.wire_count + vm_stats.inactive_count + vm_stats.active_count;
+ profile_data_stream << "used:" << total_used_count * vm_page_size << ';';
+ profile_data_stream << "free:" << vm_stats.free_count * vm_page_size << ';';
+
+ profile_data_stream << "rprvt:" << rprvt << ';';
+ profile_data_stream << "rsize:" << rsize << ';';
+ profile_data_stream << "vprvt:" << vprvt << ';';
+ profile_data_stream << "vsize:" << vsize << ';';
+
+ if (scanType & eProfileMemoryDirtyPage)
+ profile_data_stream << "dirty:" << dirty_size << ';';
+ }
- profile_data_stream << "rprvt:" << rprvt << ';';
- profile_data_stream << "rsize:" << rsize << ';';
- profile_data_stream << "vprvt:" << vprvt << ';';
- profile_data_stream << "vsize:" << vsize << ';';
- profile_data_stream << "dirty:" << dirty_size << ';';
profile_data_stream << "--end--;";
result = profile_data_stream.str();
diff --git a/lldb/tools/debugserver/source/MacOSX/MachTask.h b/lldb/tools/debugserver/source/MacOSX/MachTask.h
index 52169715407..f3fb6fb80f0 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachTask.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachTask.h
@@ -26,6 +26,7 @@
#include <string>
// Other libraries and framework includes
// Project includes
+#include "DNBDefs.h"
#include "MachException.h"
#include "MachVMMemory.h"
#include "PThreadMutex.h"
@@ -66,7 +67,7 @@ public:
nub_size_t ReadMemory (nub_addr_t addr, nub_size_t size, void *buf);
nub_size_t WriteMemory (nub_addr_t addr, nub_size_t size, const void *buf);
int GetMemoryRegionInfo (nub_addr_t addr, DNBRegionInfo *region_info);
- std::string GetProfileData ();
+ std::string GetProfileData (DNBProfileDataScanType scanType);
nub_addr_t AllocateMemory (nub_size_t size, uint32_t permissions);
nub_bool_t DeallocateMemory (nub_addr_t addr);
diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp
index d13cbfe0131..c0ce9c6ec93 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp
@@ -397,21 +397,29 @@ static void GetMemorySizes(task_t task, cpu_type_t cputype, nub_process_t pid, m
}
nub_bool_t
-MachVMMemory::GetMemoryProfile(task_t task, struct task_basic_info ti, cpu_type_t cputype, nub_process_t pid, vm_statistics_data_t &vm_stats, uint64_t &physical_memory, mach_vm_size_t &rprvt, mach_vm_size_t &rsize, mach_vm_size_t &vprvt, mach_vm_size_t &vsize, mach_vm_size_t &dirty_size)
+MachVMMemory::GetMemoryProfile(DNBProfileDataScanType scanType, task_t task, struct task_basic_info ti, cpu_type_t cputype, nub_process_t pid, vm_statistics_data_t &vm_stats, uint64_t &physical_memory, mach_vm_size_t &rprvt, mach_vm_size_t &rsize, mach_vm_size_t &vprvt, mach_vm_size_t &vsize, mach_vm_size_t &dirty_size)
{
- static mach_port_t localHost = mach_host_self();
- mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
- host_statistics(localHost, HOST_VM_INFO, (host_info_t)&vm_stats, &count);
- vm_stats.wire_count += GetStolenPages();
- physical_memory = GetPhysicalMemory();
-
- // This uses vmmap strategy. We don't use the returned rsize for now. We prefer to match top's version since that's what we do for the rest of the metrics.
- GetRegionSizes(task, rsize, dirty_size);
+ if (scanType & eProfileHostMemory)
+ physical_memory = GetPhysicalMemory();
- GetMemorySizes(task, cputype, pid, rprvt, vprvt);
+ if (scanType & eProfileMemory)
+ {
+ static mach_port_t localHost = mach_host_self();
+ mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
+ host_statistics(localHost, HOST_VM_INFO, (host_info_t)&vm_stats, &count);
+ vm_stats.wire_count += GetStolenPages();
+
+ GetMemorySizes(task, cputype, pid, rprvt, vprvt);
+
+ rsize = ti.resident_size;
+ vsize = ti.virtual_size;
+ }
- rsize = ti.resident_size;
- vsize = ti.virtual_size;
+ if (scanType & eProfileMemoryDirtyPage)
+ {
+ // This uses vmmap strategy. We don't use the returned rsize for now. We prefer to match top's version since that's what we do for the rest of the metrics.
+ GetRegionSizes(task, rsize, dirty_size);
+ }
return true;
}
diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h
index 2a8f3d13c84..0b782365d08 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h
@@ -28,7 +28,7 @@ public:
nub_size_t Write(task_t task, nub_addr_t address, const void *data, nub_size_t data_count);
nub_size_t PageSize();
nub_bool_t GetMemoryRegionInfo(task_t task, nub_addr_t address, DNBRegionInfo *region_info);
- nub_bool_t GetMemoryProfile(task_t task, struct task_basic_info ti, cpu_type_t cputype, nub_process_t pid, vm_statistics_data_t &vm_stats, uint64_t &physical_memory, mach_vm_size_t &rprvt, mach_vm_size_t &rsize, mach_vm_size_t &vprvt, mach_vm_size_t &vsize, mach_vm_size_t &dirty_size);
+ nub_bool_t GetMemoryProfile(DNBProfileDataScanType scanType, task_t task, struct task_basic_info ti, cpu_type_t cputype, nub_process_t pid, vm_statistics_data_t &vm_stats, uint64_t &physical_memory, mach_vm_size_t &rprvt, mach_vm_size_t &rsize, mach_vm_size_t &vprvt, mach_vm_size_t &vsize, mach_vm_size_t &dirty_size);
protected:
nub_size_t MaxBytesLeftInPage(nub_addr_t addr, nub_size_t count);
diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index 5177c0e7299..f3612e866c6 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -3645,14 +3645,32 @@ RNBRemote::HandlePacket_MemoryRegionInfo (const char *p)
return SendPacket (ostrm.str());
}
+// qGetProfileData;scan_type:0xYYYYYYY
rnb_err_t
RNBRemote::HandlePacket_GetProfileData (const char *p)
{
nub_process_t pid = m_ctx.ProcessID();
if (pid == INVALID_NUB_PROCESS)
return SendPacket ("OK");
-
- std::string data = DNBProcessGetProfileData(pid);
+
+ StringExtractor packet(p += sizeof ("qGetProfileData"));
+ DNBProfileDataScanType scan_type = eProfileAll;
+ std::string name;
+ std::string value;
+ while (packet.GetNameColonValue(name, value))
+ {
+ if (name.compare ("scan_type") == 0)
+ {
+ std::istringstream iss(value);
+ uint32_t int_value = 0;
+ if (iss >> std::hex >> int_value)
+ {
+ scan_type = (DNBProfileDataScanType)int_value;
+ }
+ }
+ }
+
+ std::string data = DNBProcessGetProfileData(pid, scan_type);
if (!data.empty())
{
return SendPacket (data.c_str());
@@ -3663,18 +3681,18 @@ RNBRemote::HandlePacket_GetProfileData (const char *p)
}
}
-
-// QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX;
+// QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX;scan_type:0xYYYYYYY
rnb_err_t
RNBRemote::HandlePacket_SetEnableAsyncProfiling (const char *p)
{
nub_process_t pid = m_ctx.ProcessID();
if (pid == INVALID_NUB_PROCESS)
- return SendPacket ("");
+ return SendPacket ("OK");
- StringExtractor packet(p += sizeof ("QSetEnableAsyncProfiling:") - 1);
+ StringExtractor packet(p += sizeof ("QSetEnableAsyncProfiling"));
bool enable = false;
uint64_t interval_usec = 0;
+ DNBProfileDataScanType scan_type = eProfileAll;
std::string name;
std::string value;
while (packet.GetNameColonValue(name, value))
@@ -3687,13 +3705,23 @@ RNBRemote::HandlePacket_SetEnableAsyncProfiling (const char *p)
{
interval_usec = strtoul(value.c_str(), NULL, 10);
}
+ else if (name.compare ("scan_type") == 0)
+ {
+ std::istringstream iss(value);
+ uint32_t int_value = 0;
+ if (iss >> std::hex >> int_value)
+ {
+ scan_type = (DNBProfileDataScanType)int_value;
+ }
+ }
}
if (interval_usec == 0)
{
enable = 0;
}
- DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec);
+
+ DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec, scan_type);
return SendPacket ("OK");
}
OpenPOWER on IntegriCloud