| 488 | } |
| 489 | |
| 490 | static bool |
| 491 | prof_dump(tsd_t *tsd, bool propagate_err, const char *filename, |
| 492 | bool leakcheck) { |
| 493 | cassert(config_prof); |
| 494 | assert(tsd_reentrancy_level_get(tsd) == 0); |
| 495 | |
| 496 | prof_tdata_t * tdata = prof_tdata_get(tsd, true); |
| 497 | if (tdata == NULL) { |
| 498 | return true; |
| 499 | } |
| 500 | |
| 501 | prof_dump_arg_t arg = {/* handle_error_locally */ !propagate_err, |
| 502 | /* error */ false, /* prof_dump_fd */ -1}; |
| 503 | |
| 504 | pre_reentrancy(tsd, NULL); |
| 505 | malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_mtx); |
| 506 | |
| 507 | prof_dump_open(&arg, filename); |
| 508 | buf_writer_t buf_writer; |
| 509 | bool err = buf_writer_init(tsd_tsdn(tsd), &buf_writer, prof_dump_flush, |
| 510 | &arg, prof_dump_buf, PROF_DUMP_BUFSIZE); |
| 511 | assert(!err); |
| 512 | prof_dump_impl(tsd, buf_writer_cb, &buf_writer, tdata, leakcheck); |
| 513 | prof_dump_maps(&buf_writer); |
| 514 | buf_writer_terminate(tsd_tsdn(tsd), &buf_writer); |
| 515 | prof_dump_close(&arg); |
| 516 | |
| 517 | prof_dump_hook_t dump_hook = prof_dump_hook_get(); |
| 518 | if (dump_hook != NULL) { |
| 519 | dump_hook(filename); |
| 520 | } |
| 521 | malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_mtx); |
| 522 | post_reentrancy(tsd); |
| 523 | |
| 524 | return arg.error; |
| 525 | } |
| 526 | |
| 527 | /* |
| 528 | * If profiling is off, then PROF_DUMP_FILENAME_LEN is 1, so we'll end up |
no test coverage detected