1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 20:17:44 +00:00

Kernel: Make Process::dump_perfcore OOM-fallible using KString

This commit is contained in:
Idan Horowitz 2022-01-12 23:21:08 +02:00 committed by Brian Gianforcaro
parent 010a37f997
commit 0fc25273e4
2 changed files with 15 additions and 24 deletions

View file

@ -519,53 +519,42 @@ ErrorOr<void> Process::dump_core()
return coredump->write(); return coredump->write();
} }
bool Process::dump_perfcore() ErrorOr<void> Process::dump_perfcore()
{ {
VERIFY(is_dumpable()); VERIFY(is_dumpable());
VERIFY(m_perf_event_buffer); VERIFY(m_perf_event_buffer);
dbgln("Generating perfcore for pid: {}", pid().value()); dbgln("Generating perfcore for pid: {}", pid().value());
// Try to generate a filename which isn't already used. // Try to generate a filename which isn't already used.
auto base_filename = String::formatted("{}_{}", name(), pid().value()); auto base_filename = TRY(KString::formatted("{}_{}", name(), pid().value()));
auto perfcore_filename = String::formatted("{}.profile", base_filename); auto perfcore_filename = TRY(KString::formatted("{}.profile", base_filename));
RefPtr<OpenFileDescription> description; RefPtr<OpenFileDescription> description;
for (size_t attempt = 1; attempt <= 10; ++attempt) { for (size_t attempt = 1; attempt <= 10; ++attempt) {
auto description_or_error = VirtualFileSystem::the().open(perfcore_filename, O_CREAT | O_EXCL, 0400, current_directory(), UidAndGid { 0, 0 }); auto description_or_error = VirtualFileSystem::the().open(perfcore_filename->view(), O_CREAT | O_EXCL, 0400, current_directory(), UidAndGid { 0, 0 });
if (!description_or_error.is_error()) { if (!description_or_error.is_error()) {
description = description_or_error.release_value(); description = description_or_error.release_value();
break; break;
} }
perfcore_filename = String::formatted("{}.{}.profile", base_filename, attempt); perfcore_filename = TRY(KString::formatted("{}.{}.profile", base_filename, attempt));
} }
if (!description) { if (!description) {
dbgln("Failed to generate perfcore for pid {}: Could not generate filename for the perfcore file.", pid().value()); dbgln("Failed to generate perfcore for pid {}: Could not generate filename for the perfcore file.", pid().value());
return false; return EEXIST;
} }
auto builder_or_error = KBufferBuilder::try_create(); auto builder = TRY(KBufferBuilder::try_create());
if (builder_or_error.is_error()) { TRY(m_perf_event_buffer->to_json(builder));
dbgln("Failed to generate perfcore for pid {}: Could not allocate KBufferBuilder.", pid());
return false;
}
auto builder = builder_or_error.release_value();
if (m_perf_event_buffer->to_json(builder).is_error()) {
dbgln("Failed to generate perfcore for pid {}: Could not serialize performance events to JSON.", pid().value());
return false;
}
auto json = builder.build(); auto json = builder.build();
if (!json) { if (!json) {
dbgln("Failed to generate perfcore for pid {}: Could not allocate buffer.", pid().value()); dbgln("Failed to generate perfcore for pid {}: Could not allocate buffer.", pid().value());
return false; return ENOMEM;
} }
auto json_buffer = UserOrKernelBuffer::for_kernel_buffer(json->data()); auto json_buffer = UserOrKernelBuffer::for_kernel_buffer(json->data());
if (description->write(json_buffer, json->size()).is_error()) { TRY(description->write(json_buffer, json->size()));
dbgln("Failed to generate perfcore for pid {}: Could not write to perfcore file.", pid().value());
return false;
}
dbgln("Wrote perfcore for pid {} to {}", pid().value(), perfcore_filename); dbgln("Wrote perfcore for pid {} to {}", pid().value(), perfcore_filename);
return true; return {};
} }
void Process::finalize() void Process::finalize()
@ -585,7 +574,9 @@ void Process::finalize()
} }
} }
if (m_perf_event_buffer) { if (m_perf_event_buffer) {
dump_perfcore(); auto result = dump_perfcore();
if (result.is_error())
critical_dmesgln("Failed to write perfcore: {}", result.error());
TimeManagement::the().disable_profile_timer(); TimeManagement::the().disable_profile_timer();
} }
} }

View file

@ -528,7 +528,7 @@ private:
void kill_threads_except_self(); void kill_threads_except_self();
void kill_all_threads(); void kill_all_threads();
ErrorOr<void> dump_core(); ErrorOr<void> dump_core();
bool dump_perfcore(); ErrorOr<void> dump_perfcore();
bool create_perf_events_buffer_if_needed(); bool create_perf_events_buffer_if_needed();
void delete_perf_events_buffer(); void delete_perf_events_buffer();