// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "crashdumpwriter_vfs.hpp" #include #include #include #include "purefs/vfs_subsystem.hpp" #include #include #include #include #include #include #include #include namespace { constexpr inline auto suffix = "_crashdump.hex"; constexpr inline auto file_index = ".1"; // Crashdump filename pattern: // [serial-number]_[timestamp-in-seconds]_crashdump.hex.[index] // [index] was added to ensure resistance to the device date retraction inline std::string generate_crashdump_filename() { const auto crash_time = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()) .count(); auto filename = std::string("/") + crashdump::getSerialNumber() + "_" + std::to_string(crash_time) + suffix + file_index; return filename; } } // namespace namespace crashdump { void CrashDumpWriterVFS::openDump() { const auto crashDumpFilePath = purefs::dir::getCrashDumpsPath().string() + generate_crashdump_filename(); LOG_INFO("Crash dump %s preparing ...", crashDumpFilePath.c_str()); if (!rotator.rotateFiles(purefs::dir::getCrashDumpsPath())) { LOG_FATAL("Failed to rotate crash dumps errno: %i", errno); _exit_backtrace(-1, false); } file = std::fopen(crashDumpFilePath.c_str(), "w"); if (!file) { LOG_FATAL("Failed to open crash dump file errno %i", errno); _exit_backtrace(-1, false); } } void CrashDumpWriterVFS::saveDump() { LOG_INFO("Crash dump create finished."); fflush(file); fsync(fileno(file)); std::fclose(file); } void CrashDumpWriterVFS::writeBytes(const uint8_t *buff, std::size_t size) { if (std::fwrite(buff, sizeof(*buff), size, file) != size) { LOG_FATAL("Unable to write crash dump errno: %i", errno); _exit_backtrace(-1, false); } } void CrashDumpWriterVFS::writeHalfWords(const uint16_t *buff, std::size_t size) { if (std::fwrite(buff, sizeof(*buff), size, file) != size) { LOG_FATAL("Unable to write crash dump errno: %i", errno); _exit_backtrace(-1, false); } } void CrashDumpWriterVFS::writeWords(const uint32_t *buff, std::size_t size) { if (std::fwrite(buff, sizeof(*buff), size, file) != size) { LOG_FATAL("Unable to write crash dump errno: %i", errno); _exit_backtrace(-1, false); } } } // namespace crashdump