[Lldb-commits] [lldb] r163441 - /lldb/trunk/examples/darwin/heap_find/heap/heap_find.cpp
Greg Clayton
gclayton at apple.com
Fri Sep 7 18:16:16 PDT 2012
Author: gclayton
Date: Fri Sep 7 20:16:16 2012
New Revision: 163441
URL: http://llvm.org/viewvc/llvm-project?rev=163441&view=rev
Log:
Don't allocate memory when enumerting stack. We now have fixed size buffers to avoid this issue.
Modified:
lldb/trunk/examples/darwin/heap_find/heap/heap_find.cpp
Modified: lldb/trunk/examples/darwin/heap_find/heap/heap_find.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/darwin/heap_find/heap/heap_find.cpp?rev=163441&r1=163440&r2=163441&view=diff
==============================================================================
--- lldb/trunk/examples/darwin/heap_find/heap/heap_find.cpp (original)
+++ lldb/trunk/examples/darwin/heap_find/heap/heap_find.cpp Fri Sep 7 20:16:16 2012
@@ -201,16 +201,120 @@
const void *address;
uint64_t argument;
uint32_t type_flags;
- std::vector<uintptr_t> frames;
+ uint32_t num_frames;
+ mach_vm_address_t frames[MAX_FRAMES];
+};
+
+class MatchResults
+{
+ enum {
+ k_max_entries = 8 * 1024
+ };
+public:
+ MatchResults () :
+ m_size(0)
+ {
+ }
+
+ void
+ clear()
+ {
+ m_size = 0;
+ }
+
+ bool
+ empty() const
+ {
+ return m_size == 0;
+ }
+
+ void
+ push_back (const malloc_match& m)
+ {
+ if (m_size < k_max_entries - 1)
+ {
+ m_entries[m_size] = m;
+ m_size++;
+ }
+ }
+
+ malloc_match *
+ data ()
+ {
+ // If empty, return NULL
+ if (empty())
+ return NULL;
+ // In not empty, terminate and return the result
+ malloc_match terminator_entry = { NULL, 0, 0 };
+ // We always leave room for an empty entry at the end
+ m_entries[m_size + 1] = terminator_entry;
+ return m_entries;
+ }
+
+protected:
+ malloc_match m_entries[k_max_entries];
+ uint32_t m_size;
+};
+
+class MallocStackLoggingEntries
+{
+ enum { k_max_entries = 128 };
+public:
+ MallocStackLoggingEntries () :
+ m_size(0)
+ {
+ }
+
+ void
+ clear()
+ {
+ m_size = 0;
+ }
+
+ bool
+ empty() const
+ {
+ return m_size == 0;
+ }
+
+
+ malloc_stack_entry *
+ next ()
+ {
+ if (m_size < k_max_entries - 1)
+ {
+ malloc_stack_entry * result = m_entries + m_size;
+ ++m_size;
+ return result;
+ }
+ return NULL; // Out of entries...
+ }
+
+ malloc_stack_entry *
+ data ()
+ {
+ // If empty, return NULL
+ if (empty())
+ return NULL;
+ // In not empty, terminate and return the result
+ m_entries[m_size + 1].address = NULL;
+ m_entries[m_size + 1].argument = 0;
+ m_entries[m_size + 1].type_flags = 0;
+ m_entries[m_size + 1].num_frames = 0;
+ return m_entries;
+ }
+
+protected:
+ malloc_stack_entry m_entries[k_max_entries];
+ uint32_t m_size;
};
//----------------------------------------------------------------------
// Local global variables
//----------------------------------------------------------------------
-std::vector<malloc_match> g_matches;
-std::vector<malloc_stack_entry> g_malloc_stack_history;
-mach_vm_address_t g_stack_frames[MAX_FRAMES];
-char g_error_string[PATH_MAX];
+//std::vector<malloc_match> g_matches;
+MatchResults g_matches;
+MallocStackLoggingEntries g_malloc_stack_history;
//----------------------------------------------------------------------
// task_peek
@@ -296,7 +400,7 @@
{
++info->match_count;
malloc_match match = { (void *)ptr_addr, ptr_size, info->addr - ptr_addr };
- g_matches.push_back(match);
+ g_matches.push_back(match);
}
break;
@@ -413,31 +517,31 @@
static void
get_stack_for_address_enumerator(mach_stack_logging_record_t stack_record, void *task_ptr)
{
- uint32_t num_frames = 0;
- kern_return_t err = __mach_stack_logging_frames_for_uniqued_stack (*(task_t *)task_ptr,
- stack_record.stack_identifier,
- g_stack_frames,
- MAX_FRAMES,
- &num_frames);
- g_malloc_stack_history.resize(g_malloc_stack_history.size() + 1);
- g_malloc_stack_history.back().address = (void *)stack_record.address;
- g_malloc_stack_history.back().type_flags = stack_record.type_flags;
- g_malloc_stack_history.back().argument = stack_record.argument;
- if (num_frames > 0)
- g_malloc_stack_history.back().frames.assign(g_stack_frames, g_stack_frames + num_frames);
- g_malloc_stack_history.back().frames.push_back(0); // Terminate the frames with zero
+ malloc_stack_entry *stack_entry = g_malloc_stack_history.next();
+ if (stack_entry)
+ {
+ stack_entry->address = (void *)stack_record.address;
+ stack_entry->type_flags = stack_record.type_flags;
+ stack_entry->argument = stack_record.argument;
+ stack_entry->num_frames = 0;
+ stack_entry->frames[0] = 0;
+ kern_return_t err = __mach_stack_logging_frames_for_uniqued_stack (*(task_t *)task_ptr,
+ stack_record.stack_identifier,
+ stack_entry->frames,
+ MAX_FRAMES,
+ &stack_entry->num_frames);
+ // Terminate the frames with zero if there is room
+ if (stack_entry->num_frames < MAX_FRAMES)
+ stack_entry->frames[stack_entry->num_frames] = 0;
+ }
}
malloc_stack_entry *
get_stack_history_for_address (const void * addr, int history)
{
- std::vector<malloc_stack_entry> empty;
- g_malloc_stack_history.swap(empty);
if (!stack_logging_enable_logging)
- {
- strncpy(g_error_string, "error: stack logging is not enabled, set MallocStackLogging=1 in the environment when launching to enable stack logging.", sizeof(g_error_string));
return NULL;
- }
+ g_malloc_stack_history.clear();
kern_return_t err;
task_t task = mach_task_self();
if (history)
@@ -449,26 +553,28 @@
}
else
{
- uint32_t num_frames = 0;
- err = __mach_stack_logging_get_frames(task, (mach_vm_address_t)addr, g_stack_frames, MAX_FRAMES, &num_frames);
- if (err == 0 && num_frames > 0)
+ malloc_stack_entry *stack_entry = g_malloc_stack_history.next();
+ if (stack_entry)
{
- g_malloc_stack_history.resize(1);
- g_malloc_stack_history.back().address = addr;
- g_malloc_stack_history.back().type_flags = stack_logging_type_alloc;
- g_malloc_stack_history.back().argument = 0;
- if (num_frames > 0)
- g_malloc_stack_history.back().frames.assign(g_stack_frames, g_stack_frames + num_frames);
- g_malloc_stack_history.back().frames.push_back(0); // Terminate the frames with zero
+ stack_entry->address = addr;
+ stack_entry->type_flags = stack_logging_type_alloc;
+ stack_entry->argument = 0;
+ stack_entry->num_frames = 0;
+ stack_entry->frames[0] = 0;
+ err = __mach_stack_logging_get_frames(task, (mach_vm_address_t)addr, stack_entry->frames, MAX_FRAMES, &stack_entry->num_frames);
+ if (err == 0 && stack_entry->num_frames > 0)
+ {
+ // Terminate the frames with zero if there is room
+ if (stack_entry->num_frames < MAX_FRAMES)
+ stack_entry->frames[stack_entry->num_frames] = 0;
+ }
+ else
+ {
+ g_malloc_stack_history.clear();
+ }
}
}
- // Append an empty entry
- if (g_malloc_stack_history.empty())
- return NULL;
- g_malloc_stack_history.resize(g_malloc_stack_history.size() + 1);
- g_malloc_stack_history.back().address = 0;
- g_malloc_stack_history.back().type_flags = 0;
- g_malloc_stack_history.back().argument = 0;
+ // Return data if there is any
return g_malloc_stack_history.data();
}
@@ -496,10 +602,6 @@
range_callback_info_t info = { enumerate_range_in_zone, range_info_callback, &data_info };
foreach_zone_in_this_process (&info);
}
- if (g_matches.empty())
- return NULL;
- malloc_match match = { NULL, 0, 0 };
- g_matches.push_back(match);
return g_matches.data();
}
@@ -523,10 +625,6 @@
data_info.match_count = 0; // Initialize the match count to zero
data_info.done = false; // Set done to false so searching doesn't stop
range_info_callback (mach_task_self(), &data_info, stack_logging_type_generic, memory_addr, memory_size);
- if (g_matches.empty())
- return NULL;
- malloc_match match = { NULL, 0, 0 };
- g_matches.push_back(match);
return g_matches.data();
}
@@ -551,10 +649,6 @@
data_info.done = false; // Set done to false so searching doesn't stop
range_callback_info_t info = { enumerate_range_in_zone, range_info_callback, &data_info };
foreach_zone_in_this_process (&info);
- if (g_matches.empty())
- return NULL;
- malloc_match match = { NULL, 0, 0 };
- g_matches.push_back(match);
return g_matches.data();
}
@@ -583,10 +677,6 @@
data_info.done = false; // Set done to false so searching doesn't stop
range_callback_info_t info = { enumerate_range_in_zone, range_info_callback, &data_info };
foreach_zone_in_this_process (&info);
- if (g_matches.empty())
- return NULL;
- malloc_match match = { NULL, 0, 0 };
- g_matches.push_back(match);
return g_matches.data();
}
@@ -608,9 +698,5 @@
data_info.done = false; // Set done to false so searching doesn't stop
range_callback_info_t info = { enumerate_range_in_zone, range_info_callback, &data_info };
foreach_zone_in_this_process (&info);
- if (g_matches.empty())
- return NULL;
- malloc_match match = { NULL, 0, 0 };
- g_matches.push_back(match);
return g_matches.data();
}
More information about the lldb-commits
mailing list