malloc_t real_malloc = nullptr;
free_t real_free = nullptr;
-struct IPCacheEntry {
+struct IPCacheEntry
+{
size_t id;
bool skip;
bool stop;
};
-thread_local std::unordered_map<unw_word_t, IPCacheEntry> ipCache;
+// must be kept separately from ThreadData to ensure it stays valid
+// even until after ThreadData is destroyed
thread_local bool in_handler = false;
+
+struct ThreadData
+{
+ ThreadData()
+ {
+ bool wasInHandler = in_handler;
+ in_handler = true;
+ ipCache.reserve(1024);
+ in_handler = wasInHandler;
+ }
+
+ ~ThreadData()
+ {
+ in_handler = true;
+ }
+
+ std::unordered_map<unw_word_t, IPCacheEntry> ipCache;
+};
+
+thread_local ThreadData threadData;
+
std::atomic<size_t> next_id;
void print_caller()
return;
}
+ auto& ipCache = threadData.ipCache;
+
while (unw_step(&cursor) > 0)
{
unw_word_t ip;
real_malloc = findReal<malloc_t>("malloc");
real_free = findReal<free_t>("free");
- ipCache.reserve(1024);
-
in_handler = false;
}
if (!in_handler) {
in_handler = true;
- printf("+%ld ", size);
+ printf("+%ld:%p ", size, ret);
print_caller();
printf("\n");
in_handler = false;
real_free(ptr);
+ if (!in_handler) {
+ in_handler = true;
+ printf("-%p\n", ptr);
+ in_handler = false;
+ }
// TODO: actually handle this
}