Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dump Memory Usage with SIGUSR1 #10182

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions common/FileUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <pwd.h>
#include <stdexcept>
#include <sys/time.h>
#include <unistd.h>
#ifdef __linux__
#include <sys/vfs.h>
#elif defined IOS
Expand Down Expand Up @@ -387,6 +388,7 @@ namespace FileUtil
std::unique_ptr<std::vector<char>> readFile(const std::string& path, int maxSize)
{
auto data = std::make_unique<std::vector<char>>(maxSize);
data->resize(0);
caolanm marked this conversation as resolved.
Show resolved Hide resolved
return (readFile(path, *data, maxSize) >= 0) ? std::move(data) : nullptr;
}

Expand Down Expand Up @@ -427,6 +429,41 @@ namespace FileUtil
return rootPath.toString();
}

ssize_t read(int fd, void* buf, size_t nbytes)
{
ssize_t off = 0;
char* p = static_cast<char*>(buf);
for (;;)
{
if (static_cast<ssize_t>(nbytes) <= 0)
{
// Nothing to read.
break;
}

ssize_t n;
while ((n = ::read(fd, p, nbytes)) < 0 && errno == EINTR)
{
}

if (n <= 0)
{
if (n == 0) // EOF.
break;

return -1; // Error.
}

assert(n >= 0 && "Expected a positive read byte-count");
p += n;
off += n;
assert(static_cast<size_t>(n) <= nbytes && "Unexpectedly read more than requested");
nbytes -= n;
}

return off;
}

} // namespace FileUtil

namespace
Expand Down
39 changes: 10 additions & 29 deletions common/FileUtil.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,11 @@ namespace FileUtil
/// have equal size and every byte of their contents match.
bool compareFileContents(const std::string& rhsPath, const std::string& lhsPath);

/// Reads the whole file into the given buffer. Only for small files.
/// Read nbytes from fd into buf. Retries on EINTR.
/// Returns the number of bytes read, or -1 on error.
ssize_t read(int fd, void* buf, size_t nbytes);

/// Reads the whole file appending onto the given buffer. Only for small files.
/// Does *not* clear the buffer before writing to it. Returns the number of bytes read, -1 for error.
template <typename T>
ssize_t readFile(const std::string& path, T& data, int maxSize = 256 * 1024)
Expand All @@ -165,38 +169,15 @@ namespace FileUtil
}

const std::size_t originalSize = data.size();
auto remainingSize = st.st_size;
const auto remainingSize = (st.st_size > 0 ? st.st_size : maxSize);
data.resize(originalSize + remainingSize);
off_t off = originalSize;
for (;;)
{
if (remainingSize == 0)
{
// Nothing to read.
break;
}

int n;
while ((n = ::read(fd, &data[off], remainingSize)) < 0 && errno == EINTR)
{
}
const ssize_t n = read(fd, &data[originalSize], remainingSize);
::close(fd);

if (n <= 0)
{
if (n == 0) // EOF.
break;

::close(fd);
data.resize(originalSize);
return -1; // Error.
}

off += n;
remainingSize -= n;
}
data.resize(originalSize + (n <= 0 ? 0 : n));

close(fd);
return st.st_size;
return n;
}

/// Reads the whole file to memory. Only for small files.
Expand Down
18 changes: 12 additions & 6 deletions kit/Kit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2529,8 +2529,14 @@ void Document::dumpState(std::ostream& oss)
<< "\n\tduringLoad: " << _duringLoad
<< "\n\tmodified: " << name(_modified)
<< "\n\tbgSaveProc: " << _isBgSaveProcess
<< "\n\tbgSaveDisabled: "<< _isBgSaveDisabled
<< "\n";
<< "\n\tbgSaveDisabled: "<< _isBgSaveDisabled;

std::string smap;
if (const ssize_t size = FileUtil::readFile("/proc/self/smaps_rollup", smap); size <= 0)
oss << "\n smaps_rollup: <unavailable>";
else
oss << "\n smaps_rollup: " << smap;
oss << '\n';

// dumpState:
// TODO: _websocketHandler - but this is an odd one.
Expand All @@ -2542,7 +2548,7 @@ void Document::dumpState(std::ostream& oss)
<< " editorId: " << it.second->getDoc()->getEditorId()
<< " mobileAppDocId: " << it.second->getDoc()->getMobileAppDocId();
}
oss << "\n";
oss << '\n';

_deltaPool.dumpState(oss);
_sessions.dumpState(oss);
Expand All @@ -2557,7 +2563,7 @@ void Document::dumpState(std::ostream& oss)
oss << "\n\t\tviewId: " << it.first
<< " last update time(ms): " << ms;
}
oss << "\n";
oss << '\n';

oss << "\tspeedCount:";
for (const auto &it : _speedCount)
Expand All @@ -2578,14 +2584,14 @@ void Document::dumpState(std::ostream& oss)
<< " readOnly: " << it.second.isReadOnly()
<< " connected: " << it.second.isConnected();
}
oss << "\n";
oss << '\n';

char *pState = nullptr;
_loKit->dumpState("", &pState);
oss << "lok state:\n";
if (pState)
oss << pState;
oss << "\n";
oss << '\n';
}

#if !defined BUILDING_TESTS && !MOBILEAPP && !LIBFUZZER
Expand Down
4 changes: 2 additions & 2 deletions test/WopiProofTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ void WopiProofTests::testOurProof()
LOK_ASSERT_EQUAL(pairs[2].first, std::string("X-WOPI-ProofOld"));
std::string proofOld = pairs[2].second;

int64_t ticks = std::stoll(timestamp.c_str(), nullptr, 10);
int64_t ticks = std::stoll(timestamp, nullptr, 10);
verifySignature(access_token, uri, ticks, modulus, exponent, proof, testname);
verifySignature(access_token, uri, ticks, modulus, exponent, proofOld, testname);

Expand All @@ -175,7 +175,7 @@ void WopiProofTests::testOurProof()
LOK_ASSERT_EQUAL(pairs[2].first, std::string("X-WOPI-ProofOld"));
proofOld = pairs[2].second;

ticks = std::stoll(timestamp.c_str(), nullptr, 10);
ticks = std::stoll(timestamp, nullptr, 10);
verifySignature(access_token, uri, ticks, modulus, exponent, proof, testname);
verifySignature(access_token, uri, ticks, modulus, exponent, proofOld, testname);
}
Expand Down
12 changes: 12 additions & 0 deletions wsd/Admin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <chrono>
#include <iomanip>
#include <sstream>
#include <string>
#include <sys/poll.h>
#include <unistd.h>
Expand Down Expand Up @@ -695,6 +696,17 @@ void Admin::pollingThread()
}
}

bool dumpMetrics = true;
if (_dumpMetrics.compare_exchange_strong(dumpMetrics, false))
{
std::ostringstream oss;
oss << "Admin Metrics:\n";
getMetrics(oss);
const std::string str = oss.str();
fprintf(stderr, "%s\n", str.c_str());
LOG_TRC(str);
}

// Handle websockets & other work.
const auto timeout = std::chrono::milliseconds(capAndRoundInterval(
std::min(std::min(std::min(cpuWait, memWait), netWait), cleanupWait)));
Expand Down
6 changes: 6 additions & 0 deletions wsd/Admin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ class Admin : public SocketPoll

void getMetrics(std::ostringstream &metrics);

/// Will dump the metrics in the log and stderr from the Admin SocketPoll.
static void dumpMetrics() { instance()._dumpMetrics = true; }

// delete entry from _monitorSocket map
void deleteMonitorSocket(const std::string &uriWithoutParam);

Expand Down Expand Up @@ -226,6 +229,9 @@ class Admin : public SocketPoll
uint64_t _lastRecvCount;
std::string _forkitLogLevel;

/// When set, the metrics will be dumped into the log and stderr.
std::atomic_bool _dumpMetrics;

struct MonitorConnectRecord
{
void setWhen(std::chrono::steady_clock::time_point when) { _when = when; }
Expand Down
10 changes: 10 additions & 0 deletions wsd/COOLWSD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4104,6 +4104,12 @@ class COOLWSDServer
<< "\n UserInterface: " << COOLWSD::UserInterface
;

std::string smap;
if (const ssize_t size = FileUtil::readFile("/proc/self/smaps_rollup", smap); size <= 0)
os << "\n smaps_rollup: <unavailable>";
else
os << "\n smaps_rollup: " << smap;

#if !MOBILEAPP
if (FetchHttpSession)
{
Expand Down Expand Up @@ -4954,6 +4960,10 @@ void dump_state()
const std::string msg = oss.str();
fprintf(stderr, "%s\n", msg.c_str());
LOG_TRC(msg);

#if !MOBILEAPP
Admin::dumpMetrics();
#endif
}

void lslr_childroot()
Expand Down
Loading