| 441 | } |
| 442 | |
| 443 | static void |
| 444 | prof_try_log(tsd_t *tsd, const void *ptr, size_t usize, prof_tctx_t *tctx) { |
| 445 | malloc_mutex_assert_owner(tsd_tsdn(tsd), tctx->tdata->lock); |
| 446 | |
| 447 | prof_tdata_t *cons_tdata = prof_tdata_get(tsd, false); |
| 448 | if (cons_tdata == NULL) { |
| 449 | /* |
| 450 | * We decide not to log these allocations. cons_tdata will be |
| 451 | * NULL only when the current thread is in a weird state (e.g. |
| 452 | * it's being destroyed). |
| 453 | */ |
| 454 | return; |
| 455 | } |
| 456 | |
| 457 | malloc_mutex_lock(tsd_tsdn(tsd), &log_mtx); |
| 458 | |
| 459 | if (prof_logging_state != prof_logging_state_started) { |
| 460 | goto label_done; |
| 461 | } |
| 462 | |
| 463 | if (!log_tables_initialized) { |
| 464 | bool err1 = ckh_new(tsd, &log_bt_node_set, PROF_CKH_MINITEMS, |
| 465 | prof_bt_node_hash, prof_bt_node_keycomp); |
| 466 | bool err2 = ckh_new(tsd, &log_thr_node_set, PROF_CKH_MINITEMS, |
| 467 | prof_thr_node_hash, prof_thr_node_keycomp); |
| 468 | if (err1 || err2) { |
| 469 | goto label_done; |
| 470 | } |
| 471 | log_tables_initialized = true; |
| 472 | } |
| 473 | |
| 474 | nstime_t alloc_time = prof_alloc_time_get(tsd_tsdn(tsd), ptr, |
| 475 | (alloc_ctx_t *)NULL); |
| 476 | nstime_t free_time = NSTIME_ZERO_INITIALIZER; |
| 477 | nstime_update(&free_time); |
| 478 | |
| 479 | size_t sz = sizeof(prof_alloc_node_t); |
| 480 | prof_alloc_node_t *new_node = (prof_alloc_node_t *) |
| 481 | iallocztm(tsd_tsdn(tsd), sz, sz_size2index(sz), false, NULL, true, |
| 482 | arena_get(TSDN_NULL, 0, true), true); |
| 483 | |
| 484 | const char *prod_thr_name = (tctx->tdata->thread_name == NULL)? |
| 485 | "" : tctx->tdata->thread_name; |
| 486 | const char *cons_thr_name = prof_thread_name_get(tsd); |
| 487 | |
| 488 | prof_bt_t bt; |
| 489 | /* Initialize the backtrace, using the buffer in tdata to store it. */ |
| 490 | bt_init(&bt, cons_tdata->vec); |
| 491 | prof_backtrace(&bt); |
| 492 | prof_bt_t *cons_bt = &bt; |
| 493 | |
| 494 | /* We haven't destroyed tctx yet, so gctx should be good to read. */ |
| 495 | prof_bt_t *prod_bt = &tctx->gctx->bt; |
| 496 | |
| 497 | new_node->next = NULL; |
| 498 | new_node->alloc_thr_ind = prof_log_thr_index(tsd, tctx->tdata->thr_uid, |
| 499 | prod_thr_name); |
| 500 | new_node->free_thr_ind = prof_log_thr_index(tsd, cons_tdata->thr_uid, |
no test coverage detected