8
8
#include < sys/uio.h>
9
9
#include < errno.h>
10
10
#include < unistd.h>
11
+ #include < cxxabi.h>
11
12
#include < cstdio>
12
13
#include < cstring>
13
14
#include < sstream>
@@ -31,13 +32,15 @@ time_t NativeStackTrace::now;
31
32
UnwindCache NativeStackTrace::cache;
32
33
33
34
35
+
34
36
NativeStackTrace::NativeStackTrace (uint32_t pid, const unsigned char *raw_stack,
35
37
size_t stack_len, uintptr_t ip, uintptr_t sp) : error_occurred(false ) {
36
38
NativeStackTrace::stack = raw_stack;
37
39
NativeStackTrace::stack_len = stack_len;
38
40
NativeStackTrace::ip = ip;
39
41
NativeStackTrace::sp = sp;
40
42
NativeStackTrace::now = time (NULL );
43
+ logInfo (2 ," DEBUGIZA: Welcome in NativeStackTrace, pid=%d\n " , pid);
41
44
42
45
if (stack_len == 0 ) {
43
46
return ;
@@ -56,11 +59,11 @@ NativeStackTrace::NativeStackTrace(uint32_t pid, const unsigned char *raw_stack,
56
59
int res;
57
60
58
61
// Pseudo-proactive way of implementing TTL - whenever any call is made, all expired entries are removed
59
- cache_eviction (cache );
62
+ cache_eviction ();
60
63
61
64
// Check whether the entry for the process ID is presented in the cache
62
- if (!is_cached (cache, pid)) {
63
- logInfo (3 ," The given key %d is not presented in the cache\n " , pid);
65
+ if (!is_cached (pid)) {
66
+ logInfo (2 ," The given key %d is not presented in the cache\n " , pid);
64
67
65
68
as = unw_create_addr_space (&my_accessors, 0 );
66
69
upt = _UPT_create (pid);
@@ -82,12 +85,12 @@ NativeStackTrace::NativeStackTrace(uint32_t pid, const unsigned char *raw_stack,
82
85
}
83
86
84
87
// Put to the cache
85
- cache_put (cache, pid, cursor, as, upt);
88
+ cache_put (pid, cursor, as, upt);
86
89
87
90
} else {
88
- logInfo (3 ," Found entry for the given key %d in the cache\n " , pid);
91
+ logInfo (2 ," Found entry for the given key %d in the cache\n " , pid);
89
92
// Get from the cache
90
- UnwindCacheEntry cached_entry = cache_get (cache, pid);
93
+ UnwindCacheEntry cached_entry = cache_get (pid);
91
94
cursor = cached_entry.cursor ;
92
95
as = cached_entry.as ;
93
96
upt = cached_entry.upt ;
@@ -137,6 +140,11 @@ NativeStackTrace::NativeStackTrace(uint32_t pid, const unsigned char *raw_stack,
137
140
138
141
}
139
142
143
+ void NativeStackTrace::Prune_dead_pid (uint32_t dead_pid) {
144
+ logInfo (2 , " DEBUGIZA: D. Try to call cache_delete %d\n " , dead_pid);
145
+ cache_delete_key (dead_pid);
146
+ }
147
+
140
148
void NativeStackTrace::cleanup (void *upt, unw_addr_space_t as) {
141
149
if (upt) {
142
150
_UPT_destroy (upt);
@@ -230,75 +238,75 @@ bool NativeStackTrace::error_occured() const {
230
238
return error_occurred;
231
239
}
232
240
233
- bool NativeStackTrace::is_cached (const UnwindCache &map, const uint32_t &key) {
241
+ bool NativeStackTrace::is_cached (const uint32_t &key) {
234
242
try {
235
- map .at (key);
243
+ cache .at (key);
236
244
return true ;
237
245
}
238
246
catch (const std::out_of_range&) {
239
- logInfo (3 , " No entry for %d in the cache\n " , key);
247
+ logInfo (2 , " No entry for %d in the cache\n " , key);
240
248
}
241
249
return false ;
242
250
}
243
251
244
- UnwindCacheEntry NativeStackTrace::cache_get (const UnwindCache &map, const uint32_t &key) {
245
- const UnwindCacheEntry & entry = map .at (key);
252
+ UnwindCacheEntry NativeStackTrace::cache_get (const uint32_t &key) {
253
+ const UnwindCacheEntry & entry = cache .at (key);
246
254
return entry;
247
255
}
248
256
249
257
// cache_put adds a new entry to the unwind cache if the capacity allows
250
- void NativeStackTrace::cache_put (UnwindCache &mp, const uint32_t &key, const unw_cursor_t cursor, const unw_addr_space_t as, void *upt) {
258
+ void NativeStackTrace::cache_put (const uint32_t &key, const unw_cursor_t cursor, const unw_addr_space_t as, void *upt) {
251
259
// Check available capacity
252
260
if (cache_size () > NativeStackTrace::CacheMaxSizeMB*1024 *1024 - cache_single_entry_size ()) {
253
- logInfo (3 , " The cache usage is %.2f MB, close to reaching the max memory usage (%d MB)\n " , cache_size_KB ()/1024 , NativeStackTrace::CacheMaxSizeMB);
254
- logInfo (3 , " Skipping adding an entry for %d to the cache\n " , key);
261
+ logInfo (2 , " The cache usage is %.2f MB, close to reaching the max memory usage (%d MB)\n " , cache_size_KB ()/1024 , NativeStackTrace::CacheMaxSizeMB);
262
+ logInfo (2 , " Skipping adding an entry for %d to the cache\n " , key);
255
263
return ;
256
264
}
257
265
258
266
UnwindCacheEntry entry = {cursor, as, upt, now};
259
- mp [key] = entry;
260
- logInfo (3 , " New entry for %d was added to the cache\n " , key);
267
+ cache [key] = entry;
268
+ logInfo (2 , " New entry for %d was added to the cache\n " , key);
261
269
}
262
270
263
271
// cache_delete_key removes the element from the cache and destroys unwind address space and UPT
264
272
// to ensure that all memory and other resources are freed up
265
- bool NativeStackTrace::cache_delete_key (UnwindCache &mp, const uint32_t &key) {
273
+ bool NativeStackTrace::cache_delete_key (const uint32_t &key) {
266
274
UnwindCacheEntry e;
267
275
try {
268
- e = cache_get (mp, key);
276
+ e = cache_get (key);
269
277
}
270
278
catch (const std::out_of_range&) {
271
- logInfo (3 , " Failed to delete entry for %d: no such key in the cache\n " , key);
279
+ logInfo (2 , " Failed to delete entry for %d: no such key in the cache\n " , key);
272
280
return false ;
273
281
}
274
282
275
- mp .erase (key);
283
+ cache .erase (key);
276
284
cleanup (e.upt , e.as );
277
- logInfo (3 , " The entry for %d was deleted from the cache\n " , key);
285
+ logInfo (2 , " The entry for %d was deleted from the cache\n " , key);
278
286
return true ;
279
287
}
280
288
281
289
// cache_single_entry_size returns the number of bytes taken by single entry
282
- uint32_t NativeStackTrace::cache_single_entry_size () const {
290
+ uint32_t NativeStackTrace::cache_single_entry_size () {
283
291
return sizeof (decltype (cache)::key_type) + sizeof (decltype (cache)::mapped_type);
284
292
}
285
293
286
294
// cache_size returns the number of bytes currently in use by the cache
287
- uint32_t NativeStackTrace::cache_size () const {
295
+ uint32_t NativeStackTrace::cache_size () {
288
296
return sizeof (cache) + cache.size ()*cache_single_entry_size ();
289
297
}
290
298
291
299
// cache_size_KB returns the number of kilobytes currently in use by the cache
292
- float NativeStackTrace::cache_size_KB () const {
300
+ float NativeStackTrace::cache_size_KB () {
293
301
return cache_size ()/1024 ;
294
302
}
295
303
296
304
// cache_eviction removes elements older than 5 minutes (CacheMaxTTL=300)
297
- void NativeStackTrace::cache_eviction (UnwindCache &mp ) {
305
+ void NativeStackTrace::cache_eviction () {
298
306
std::vector<uint32_t > keys_to_delete;
299
307
float _prev_cache_size = cache_size_KB ();
300
308
301
- for (std::map<uint32_t , UnwindCacheEntry>::iterator iter = mp .begin (); iter != mp .end (); ++iter)
309
+ for (std::map<uint32_t , UnwindCacheEntry>::iterator iter = cache .begin (); iter != cache .end (); ++iter)
302
310
{
303
311
uint32_t k = iter->first ;
304
312
const UnwindCacheEntry & e = iter->second ;
@@ -310,13 +318,13 @@ void NativeStackTrace::cache_eviction(UnwindCache &mp) {
310
318
311
319
// Delete expired entries
312
320
for ( size_t i = 0 ; i < keys_to_delete.size (); i++ ) {
313
- cache_delete_key (mp, keys_to_delete[i]);
321
+ cache_delete_key (keys_to_delete[i]);
314
322
}
315
323
316
324
if (keys_to_delete.size () > 0 ) {
317
325
float _cache_size = cache_size_KB ();
318
- logInfo (3 ," Evicted %d item(s) from the cache\n " , keys_to_delete.size ());
319
- logInfo (3 ," The cache usage after eviction action is %.2f KB (released %.2f KB)\n " , _cache_size, _prev_cache_size - _cache_size);
326
+ logInfo (2 ," Evicted %d item(s) from the cache\n " , keys_to_delete.size ());
327
+ logInfo (2 ," The cache usage after eviction action is %.2f KB (released %.2f KB)\n " , _cache_size, _prev_cache_size - _cache_size);
320
328
}
321
329
}
322
330
0 commit comments