TODO(bevers): Add a way to dump an intermediate profile without stopping the data collection.
| 728 | // TODO(bevers): Add a way to dump an intermediate profile without |
| 729 | // stopping the data collection. |
| 730 | Future<http::Response> MemoryProfiler::stop( |
| 731 | const http::Request& request, |
| 732 | const Option<http::authentication::Principal>&) |
| 733 | { |
| 734 | if (!detectJemalloc()) { |
| 735 | return http::BadRequest(string(JEMALLOC_NOT_DETECTED_MESSAGE) + ".\n"); |
| 736 | } |
| 737 | |
| 738 | Try<bool> active = jemalloc::profilingActive(); |
| 739 | if (active.isError()) { |
| 740 | return http::BadRequest( |
| 741 | "Error interfacing with jemalloc: " + active.error() + ".\n"); |
| 742 | } |
| 743 | |
| 744 | if (!currentRun.isSome() && active.get()) { |
| 745 | // TODO(bevers): Allow stopping even in this case. |
| 746 | return http::BadRequest( |
| 747 | "Profiling is active, but was not started by libprocess. Accessing the" |
| 748 | " raw profile through libprocess is currently not supported.\n"); |
| 749 | } |
| 750 | |
| 751 | // If stop is successful or a no-op, `jemallocRawProfile` will be `Some`. |
| 752 | stopAndGenerateRawProfile(); |
| 753 | |
| 754 | if (rawProfile.isError()) { |
| 755 | return http::BadRequest(rawProfile.error() + ".\n"); |
| 756 | } |
| 757 | |
| 758 | Try<bool> stillActive = jemalloc::profilingActive(); |
| 759 | CHECK(stillActive.isError() || !stillActive.get()); |
| 760 | |
| 761 | const string message = |
| 762 | "Successfully stopped memory profiling run." |
| 763 | " Use one of the provided URLs to download results." |
| 764 | " Note that in order to generate graphs or symbolized profiles," |
| 765 | " jeprof must be installed on the host machine and generation of" |
| 766 | " these files can take several minutes."; |
| 767 | |
| 768 | const string id = stringify(rawProfile->getId()); |
| 769 | |
| 770 | JSON::Object result; |
| 771 | result.values["id"] = id; |
| 772 | result.values["message"] = message; |
| 773 | |
| 774 | result.values["url_raw_profile"] = |
| 775 | "/" + this->self().id + "/download/raw?id=" + id; |
| 776 | |
| 777 | result.values["url_graph_profile"] = |
| 778 | "/" + this->self().id + "/download/graph?id=" + id; |
| 779 | |
| 780 | result.values["url_symbolized_profile"] = |
| 781 | "/" + this->self().id + "/download/text?id=" + id; |
| 782 | |
| 783 | return http::OK(result); |
| 784 | } |
| 785 | |
| 786 | |
| 787 | Future<http::Response> MemoryProfiler::downloadRawProfile( |
nothing calls this directly
no test coverage detected