File: mallocinfohandler.cpp

package info (click to toggle)
icinga2 2.15.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 20,040 kB
  • sloc: cpp: 97,870; sql: 3,261; cs: 1,636; yacc: 1,584; sh: 1,009; ansic: 890; lex: 420; python: 80; makefile: 62; javascript: 12
file content (95 lines) | stat: -rw-r--r-- 2,097 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/* Icinga 2 | (c) 2024 Icinga GmbH | GPLv2+ */

#include "base/defer.hpp"
#include "remote/filterutility.hpp"
#include "remote/httputility.hpp"
#include "remote/mallocinfohandler.hpp"
#include <cstddef>
#include <cstdio>
#include <string>

#ifdef HAVE_MALLOC_INFO
#	include <errno.h>
#	include <malloc.h>
#endif /* HAVE_MALLOC_INFO */

using namespace icinga;

REGISTER_URLHANDLER("/v1/debug/malloc_info", MallocInfoHandler);

bool MallocInfoHandler::HandleRequest(
	const WaitGroup::Ptr&,
	AsioTlsStream&,
	const ApiUser::Ptr& user,
	boost::beast::http::request<boost::beast::http::string_body>& request,
	const Url::Ptr& url,
	boost::beast::http::response<boost::beast::http::string_body>& response,
	const Dictionary::Ptr& params,
	boost::asio::yield_context&,
	HttpServerConnection&
)
{
	namespace http = boost::beast::http;

	if (url->GetPath().size() != 3) {
		return false;
	}

	if (request.method() != http::verb::get) {
		return false;
	}

	FilterUtility::CheckPermission(user, "debug");

#ifndef HAVE_MALLOC_INFO
	HttpUtility::SendJsonError(response, params, 501, "malloc_info(3) not available.");
#else /* HAVE_MALLOC_INFO */
	char* buf = nullptr;
	size_t bufSize = 0;
	FILE* f = nullptr;

	Defer release ([&f, &buf]() {
		if (f) {
			(void)fclose(f);
		}

		free(buf);
	});

	f = open_memstream(&buf, &bufSize);

	if (!f) {
		auto error (errno);

		BOOST_THROW_EXCEPTION(posix_error()
			<< boost::errinfo_api_function("open_memstream")
			<< boost::errinfo_errno(error));
	}

	if (malloc_info(0, f)) {
		auto error (errno);

		BOOST_THROW_EXCEPTION(posix_error()
			<< boost::errinfo_api_function("malloc_info")
			<< boost::errinfo_errno(error));
	}

	auto closeErr (fclose(f));
	f = nullptr;

	if (closeErr) {
		auto error (errno);

		BOOST_THROW_EXCEPTION(posix_error()
			<< boost::errinfo_api_function("fclose")
			<< boost::errinfo_errno(error));
	}

	response.result(200);
	response.set(http::field::content_type, "application/xml");
	response.body() = std::string(buf, bufSize);
	response.content_length(response.body().size());
#endif /* HAVE_MALLOC_INFO */

	return true;
}