// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/blob/master/LICENSE.md #include "crashdumpwriter_vfs.hpp" #include #include #include #include #include #include #include #include /* Crashdump filename pattern: * crashdump_[os-metadata]_[timestamp-in-seconds].hex.[index] * where [os-metadata] is in [product]_[os-version]_[commit-hash]-[serial-number] form. * [index] was added to ensure resistance to the device date retraction. */ namespace { inline constexpr auto prefix = "crashdump"; inline constexpr auto extension = ".hex"; inline constexpr auto file_index = ".1"; inline constexpr auto separator = "_"; inline std::string generateCrashdumpFilename() { const auto crashTime = std::time(nullptr); const auto &osMetadata = Store::CrashdumpMetadata::getInstance().getMetadataString(); return (std::string(prefix) + separator + osMetadata + separator + std::to_string(crashTime) + extension + file_index); } } // namespace namespace crashdump { void CrashDumpWriterVFS::openDump() { const auto crashdumpFilePath = purefs::dir::getCrashDumpsPath() / generateCrashdumpFilename(); LOG_INFO("Preparing crashdump '%s'...", crashdumpFilePath.c_str()); if (!rotator.rotateFiles(purefs::dir::getCrashDumpsPath())) { LOG_FATAL("Failed to rotate crashdump, errno: %d", errno); _exit_backtrace(-1, false); } file = std::fopen(crashdumpFilePath.c_str(), "w"); if (file == nullptr) { LOG_FATAL("Failed to open crashdump file '%s', errno: %d", crashdumpFilePath.c_str(), errno); _exit_backtrace(-1, false); } } void CrashDumpWriterVFS::saveDump() { LOG_INFO("Crashdump created successfully!"); std::fflush(file); fsync(fileno(file)); std::fclose(file); } void CrashDumpWriterVFS::writeBytes(const std::uint8_t *buff, std::size_t size) { if (std::fwrite(buff, sizeof(*buff), size, file) != size) { LOG_FATAL("Unable to write crashdump, errno: %d", errno); _exit_backtrace(-1, false); } } void CrashDumpWriterVFS::writeHalfWords(const std::uint16_t *buff, std::size_t size) { if (std::fwrite(buff, sizeof(*buff), size, file) != size) { LOG_FATAL("Unable to write crashdump, errno: %d", errno); _exit_backtrace(-1, false); } } void CrashDumpWriterVFS::writeWords(const std::uint32_t *buff, std::size_t size) { if (std::fwrite(buff, sizeof(*buff), size, file) != size) { LOG_FATAL("Unable to write crashdump, errno: %d", errno); _exit_backtrace(-1, false); } } } // namespace crashdump