Increase default backtrace depth from 4 to 128.
Increase the default backtrace depth, because shallow backtraces tend to result in confusing pprof output graphs.
This commit is contained in:
parent
a881cd2c61
commit
588a32cd84
@ -436,7 +436,7 @@ in these cases.
|
|||||||
@roff_prof@.It B
|
@roff_prof@.It B
|
||||||
@roff_prof@Double/halve the maximum backtrace depth when profiling memory
|
@roff_prof@Double/halve the maximum backtrace depth when profiling memory
|
||||||
@roff_prof@allocation activity.
|
@roff_prof@allocation activity.
|
||||||
@roff_prof@The default is 4.
|
@roff_prof@The default is 128.
|
||||||
.It C
|
.It C
|
||||||
Double/halve the size of the maximum size class that is a multiple of the
|
Double/halve the size of the maximum size class that is a multiple of the
|
||||||
cacheline size (64).
|
cacheline size (64).
|
||||||
|
@ -9,7 +9,7 @@ typedef struct prof_ctx_s prof_ctx_t;
|
|||||||
typedef struct prof_tcache_s prof_tcache_t;
|
typedef struct prof_tcache_s prof_tcache_t;
|
||||||
|
|
||||||
/* Option defaults. */
|
/* Option defaults. */
|
||||||
#define LG_PROF_BT_MAX_DEFAULT 2
|
#define LG_PROF_BT_MAX_DEFAULT 7
|
||||||
#define LG_PROF_SAMPLE_DEFAULT 0
|
#define LG_PROF_SAMPLE_DEFAULT 0
|
||||||
#define LG_PROF_INTERVAL_DEFAULT -1
|
#define LG_PROF_INTERVAL_DEFAULT -1
|
||||||
#define LG_PROF_TCMAX_DEFAULT -1
|
#define LG_PROF_TCMAX_DEFAULT -1
|
||||||
@ -17,10 +17,13 @@ typedef struct prof_tcache_s prof_tcache_t;
|
|||||||
/*
|
/*
|
||||||
* Hard limit on stack backtrace depth. Note that the version of
|
* Hard limit on stack backtrace depth. Note that the version of
|
||||||
* prof_backtrace() that is based on __builtin_return_address() necessarily has
|
* prof_backtrace() that is based on __builtin_return_address() necessarily has
|
||||||
* a hard-coded number of backtrace frame handlers, so increasing
|
* a hard-coded number of backtrace frame handlers.
|
||||||
* LG_PROF_BT_MAX requires changing prof_backtrace().
|
|
||||||
*/
|
*/
|
||||||
#define LG_PROF_BT_MAX 7 /* >= LG_PROF_BT_MAX_DEFAULT */
|
#if (defined(JEMALLOC_PROF_LIBGCC) || defined(JEMALLOC_PROF_LIBUNWIND))
|
||||||
|
# define LG_PROF_BT_MAX ((ZU(1) << (LG_SIZEOF_PTR+3)) - 1)
|
||||||
|
#else
|
||||||
|
# define LG_PROF_BT_MAX 7 /* >= LG_PROF_BT_MAX_DEFAULT */
|
||||||
|
#endif
|
||||||
#define PROF_BT_MAX (1U << LG_PROF_BT_MAX)
|
#define PROF_BT_MAX (1U << LG_PROF_BT_MAX)
|
||||||
|
|
||||||
/* Initial hash table size. */
|
/* Initial hash table size. */
|
||||||
|
@ -52,7 +52,6 @@ static __thread prof_tcache_t *prof_tcache_tls
|
|||||||
pthread_setspecific(prof_tcache_tsd, (void *)(v)); \
|
pthread_setspecific(prof_tcache_tsd, (void *)(v)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Same contents as b2cnt_tls, but initialized such that the TSD destructor is
|
* Same contents as b2cnt_tls, but initialized such that the TSD destructor is
|
||||||
* called when a thread exits, so that prof_tcache_tls contents can be merged,
|
* called when a thread exits, so that prof_tcache_tls contents can be merged,
|
||||||
@ -60,6 +59,29 @@ static __thread prof_tcache_t *prof_tcache_tls
|
|||||||
*/
|
*/
|
||||||
static pthread_key_t prof_tcache_tsd;
|
static pthread_key_t prof_tcache_tsd;
|
||||||
|
|
||||||
|
/* Thread-specific backtrace vector, used for calls to prof_backtrace(). */
|
||||||
|
#ifndef NO_TLS
|
||||||
|
static __thread void **vec_tls
|
||||||
|
JEMALLOC_ATTR(tls_model("initial-exec"));
|
||||||
|
# define VEC_GET() vec_tls
|
||||||
|
# define VEC_SET(v) do { \
|
||||||
|
vec_tls = (v); \
|
||||||
|
pthread_setspecific(vec_tsd, (void *)(v)); \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
# define VEC_GET() ((ckh_t *)pthread_getspecific(vec_tsd))
|
||||||
|
# define VEC_SET(v) do { \
|
||||||
|
pthread_setspecific(vec_tsd, (void *)(v)); \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Same contents as vec_tls, but initialized such that the TSD destructor is
|
||||||
|
* called when a thread exits, so that vec_tls contents can be merged,
|
||||||
|
* unlinked, and deallocated.
|
||||||
|
*/
|
||||||
|
static pthread_key_t vec_tsd;
|
||||||
|
|
||||||
|
|
||||||
/* (1U << opt_lg_prof_bt_max). */
|
/* (1U << opt_lg_prof_bt_max). */
|
||||||
static unsigned prof_bt_max;
|
static unsigned prof_bt_max;
|
||||||
|
|
||||||
@ -158,6 +180,7 @@ static void prof_bt_hash(const void *key, unsigned minbits, size_t *hash1,
|
|||||||
size_t *hash2);
|
size_t *hash2);
|
||||||
static bool prof_bt_keycomp(const void *k1, const void *k2);
|
static bool prof_bt_keycomp(const void *k1, const void *k2);
|
||||||
static void prof_tcache_cleanup(void *arg);
|
static void prof_tcache_cleanup(void *arg);
|
||||||
|
static void vec_cleanup(void *arg);
|
||||||
#ifdef NO_TLS
|
#ifdef NO_TLS
|
||||||
static void prof_sample_state_thread_cleanup(void *arg);
|
static void prof_sample_state_thread_cleanup(void *arg);
|
||||||
#endif
|
#endif
|
||||||
@ -632,9 +655,17 @@ prof_thr_cnt_t *
|
|||||||
prof_alloc_prep(size_t size)
|
prof_alloc_prep(size_t size)
|
||||||
{
|
{
|
||||||
prof_thr_cnt_t *ret;
|
prof_thr_cnt_t *ret;
|
||||||
void *vec[prof_bt_max];
|
void **vec;
|
||||||
prof_bt_t bt;
|
prof_bt_t bt;
|
||||||
|
|
||||||
|
vec = VEC_GET();
|
||||||
|
if (vec == NULL) {
|
||||||
|
vec = imalloc(sizeof(void *) * prof_bt_max);
|
||||||
|
if (vec == NULL)
|
||||||
|
return (NULL);
|
||||||
|
VEC_SET(vec);
|
||||||
|
}
|
||||||
|
|
||||||
if (opt_prof_active == false) {
|
if (opt_prof_active == false) {
|
||||||
/* Sampling is currently inactive, so avoid sampling. */
|
/* Sampling is currently inactive, so avoid sampling. */
|
||||||
ret = (prof_thr_cnt_t *)(uintptr_t)1U;
|
ret = (prof_thr_cnt_t *)(uintptr_t)1U;
|
||||||
@ -1161,10 +1192,8 @@ prof_dump(const char *filename, bool leakcheck, bool propagate_err)
|
|||||||
/* Merge per thread profile stats, and sum them in cnt_all. */
|
/* Merge per thread profile stats, and sum them in cnt_all. */
|
||||||
memset(&cnt_all, 0, sizeof(prof_cnt_t));
|
memset(&cnt_all, 0, sizeof(prof_cnt_t));
|
||||||
leak_nctx = 0;
|
leak_nctx = 0;
|
||||||
for (tabind = 0; ckh_iter(&bt2ctx, &tabind, NULL, &ctx.v)
|
for (tabind = 0; ckh_iter(&bt2ctx, &tabind, NULL, &ctx.v) == false;)
|
||||||
== false;) {
|
|
||||||
prof_ctx_sum(ctx.p, &cnt_all, &leak_nctx);
|
prof_ctx_sum(ctx.p, &cnt_all, &leak_nctx);
|
||||||
}
|
|
||||||
|
|
||||||
/* Dump profile header. */
|
/* Dump profile header. */
|
||||||
if (prof_write("heap profile: ", propagate_err)
|
if (prof_write("heap profile: ", propagate_err)
|
||||||
@ -1452,6 +1481,18 @@ prof_tcache_cleanup(void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vec_cleanup(void *arg)
|
||||||
|
{
|
||||||
|
void **vec;
|
||||||
|
|
||||||
|
vec = VEC_GET();
|
||||||
|
if (vec != NULL) {
|
||||||
|
idalloc(vec);
|
||||||
|
VEC_SET(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef NO_TLS
|
#ifdef NO_TLS
|
||||||
static void
|
static void
|
||||||
prof_sample_state_thread_cleanup(void *arg)
|
prof_sample_state_thread_cleanup(void *arg)
|
||||||
@ -1507,6 +1548,11 @@ prof_boot1(void)
|
|||||||
"<jemalloc>: Error in pthread_key_create()\n");
|
"<jemalloc>: Error in pthread_key_create()\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
if (pthread_key_create(&vec_tsd, vec_cleanup) != 0) {
|
||||||
|
malloc_write(
|
||||||
|
"<jemalloc>: Error in pthread_key_create()\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
#ifdef NO_TLS
|
#ifdef NO_TLS
|
||||||
if (pthread_key_create(&prof_sample_state_tsd,
|
if (pthread_key_create(&prof_sample_state_tsd,
|
||||||
prof_sample_state_thread_cleanup) != 0) {
|
prof_sample_state_thread_cleanup) != 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user