| 2693 | |
| 2694 | |
| 2695 | bool |
| 2696 | prof_log_stop(tsdn_t *tsdn) { |
| 2697 | if (!opt_prof || !prof_booted) { |
| 2698 | return true; |
| 2699 | } |
| 2700 | |
| 2701 | tsd_t *tsd = tsdn_tsd(tsdn); |
| 2702 | malloc_mutex_lock(tsdn, &log_mtx); |
| 2703 | |
| 2704 | if (prof_logging_state != prof_logging_state_started) { |
| 2705 | malloc_mutex_unlock(tsdn, &log_mtx); |
| 2706 | return true; |
| 2707 | } |
| 2708 | |
| 2709 | /* |
| 2710 | * Set the state to dumping. We'll set it to stopped when we're done. |
| 2711 | * Since other threads won't be able to start/stop/log when the state is |
| 2712 | * dumping, we don't have to hold the lock during the whole method. |
| 2713 | */ |
| 2714 | prof_logging_state = prof_logging_state_dumping; |
| 2715 | malloc_mutex_unlock(tsdn, &log_mtx); |
| 2716 | |
| 2717 | |
| 2718 | emitter_t emitter; |
| 2719 | |
| 2720 | /* Create a file. */ |
| 2721 | |
| 2722 | int fd; |
| 2723 | #ifdef JEMALLOC_JET |
| 2724 | if (prof_log_dummy) { |
| 2725 | fd = 0; |
| 2726 | } else { |
| 2727 | fd = creat(log_filename, 0644); |
| 2728 | } |
| 2729 | #else |
| 2730 | fd = creat(log_filename, 0644); |
| 2731 | #endif |
| 2732 | |
| 2733 | if (fd == -1) { |
| 2734 | malloc_printf("<jemalloc>: creat() for log file \"%s\" " |
| 2735 | " failed with %d\n", log_filename, errno); |
| 2736 | if (opt_abort) { |
| 2737 | abort(); |
| 2738 | } |
| 2739 | return true; |
| 2740 | } |
| 2741 | |
| 2742 | /* Emit to json. */ |
| 2743 | struct prof_emitter_cb_arg_s arg; |
| 2744 | arg.fd = fd; |
| 2745 | emitter_init(&emitter, emitter_output_json, &prof_emitter_write_cb, |
| 2746 | (void *)(&arg)); |
| 2747 | |
| 2748 | emitter_begin(&emitter); |
| 2749 | prof_log_emit_metadata(&emitter); |
| 2750 | prof_log_emit_threads(tsd, &emitter); |
| 2751 | prof_log_emit_traces(tsd, &emitter); |
| 2752 | prof_log_emit_allocs(tsd, &emitter); |
no test coverage detected