From e00b5ef5a46b9b3f82448f55860bcaf3a338f5f6 Mon Sep 17 00:00:00 2001 From: Lucjan Bryndza Date: Tue, 9 Nov 2021 15:02:22 +0100 Subject: [PATCH] [CP-670] Fix crash dump creation on HF Fix the crash dump on the disk partition when phone firmware Hard Fault CM7 core error. Signed-off-by: Lucjan Bryndza --- board/rt1051/crashdump/crashcatcher_impl.cpp | 30 ++++++------- board/rt1051/crashdump/crashdumpwriter.hpp | 25 ----------- .../rt1051/crashdump/crashdumpwriter_vfs.cpp | 43 +++++++++++-------- .../rt1051/crashdump/crashdumpwriter_vfs.hpp | 18 ++++---- .../drivers/src/purefs/fs/filesystem_ext4.cpp | 8 +++- .../src/thirdparty/lwext4/ext4_bdev.cpp | 11 ++++- 6 files changed, 62 insertions(+), 73 deletions(-) delete mode 100644 board/rt1051/crashdump/crashdumpwriter.hpp diff --git a/board/rt1051/crashdump/crashcatcher_impl.cpp b/board/rt1051/crashdump/crashcatcher_impl.cpp index 04d810de07ac6c93876a1336ad9fe37a4c795970..b6598166928787380112393ec397b293175f0913 100644 --- a/board/rt1051/crashdump/crashcatcher_impl.cpp +++ b/board/rt1051/crashdump/crashcatcher_impl.cpp @@ -7,24 +7,25 @@ #include #include -#include "crashdumpwriter.hpp" +#include "crashdumpwriter_vfs.hpp" #include "consoledump.hpp" +namespace +{ + crashdump::CrashDumpWriterVFS cwrite; +} + const CrashCatcherMemoryRegion *CrashCatcher_GetMemoryRegions(void) { - // board/rt1051/ldscripts/memory.ld + /* board/rt1051/ldscripts/memory.ld + * NOTE: Text section and stacks sections are intentionally ommited + * because can cause throubles in the running system + */ static const CrashCatcherMemoryRegion regions[] = { // SRAM_OC {0x20200000, 0x20210000, CRASH_CATCHER_BYTE}, // SRAM_DTC {0x20000000, 0x20070000, CRASH_CATCHER_BYTE}, - // intentionally skip text section - // BOARD_SDRAM_HEAP -#if defined(HW_SDRAM_64_MB) && (HW_SDRAM_64_MB == 1) - {0x80620000, 0x84000000, CRASH_CATCHER_BYTE}, -#else - {0x80620000, 0x81000000, CRASH_CATCHER_BYTE}, -#endif // end tag {0xFFFFFFFF, 0xFFFFFFFF, CRASH_CATCHER_BYTE}, }; @@ -35,28 +36,27 @@ const CrashCatcherMemoryRegion *CrashCatcher_GetMemoryRegions(void) void CrashCatcher_DumpStart(const CrashCatcherInfo *pInfo) { crashdump::printCrashInfo(pInfo); - crashdump::CrashDumpWriter::instance().openDump(); + cwrite.openDump(); } void CrashCatcher_DumpMemory(const void *pvMemory, CrashCatcherElementSizes elementSize, size_t elementCount) { switch (elementSize) { case CRASH_CATCHER_BYTE: - crashdump::CrashDumpWriter::instance().writeBytes(static_cast(pvMemory), elementCount); + cwrite.writeBytes(static_cast(pvMemory), elementCount); break; case CRASH_CATCHER_HALFWORD: - crashdump::CrashDumpWriter::instance().writeHalfWords(static_cast(pvMemory), - elementCount); + cwrite.writeHalfWords(static_cast(pvMemory), elementCount); break; case CRASH_CATCHER_WORD: - crashdump::CrashDumpWriter::instance().writeWords(static_cast(pvMemory), elementCount); + cwrite.writeWords(static_cast(pvMemory), elementCount); break; } } CrashCatcherReturnCodes CrashCatcher_DumpEnd(void) { - crashdump::CrashDumpWriter::instance().saveDump(); + cwrite.saveDump(); abort(); return CRASH_CATCHER_EXIT; } diff --git a/board/rt1051/crashdump/crashdumpwriter.hpp b/board/rt1051/crashdump/crashdumpwriter.hpp deleted file mode 100644 index 8f94467bd1273c5096698ce28501436fd21e1dc9..0000000000000000000000000000000000000000 --- a/board/rt1051/crashdump/crashdumpwriter.hpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. -// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md - -#pragma once - -#include - -namespace crashdump -{ - class CrashDumpWriter - { - public: - static CrashDumpWriter &instance(); - - virtual ~CrashDumpWriter() = default; - - virtual void openDump() = 0; - virtual void saveDump() = 0; - - virtual void writeBytes(const std::uint8_t *buff, std::size_t size) = 0; - virtual void writeHalfWords(const std::uint16_t *buff, std::size_t size) = 0; - virtual void writeWords(const std::uint32_t *buff, std::size_t size) = 0; - }; - -} // namespace crashdump diff --git a/board/rt1051/crashdump/crashdumpwriter_vfs.cpp b/board/rt1051/crashdump/crashdumpwriter_vfs.cpp index 84d34e569ecfebb45c6f84ba0dcb7240df6f53f2..9f3fa38900cfd50c4b7730f6e79130d57a25d3bc 100644 --- a/board/rt1051/crashdump/crashdumpwriter_vfs.cpp +++ b/board/rt1051/crashdump/crashdumpwriter_vfs.cpp @@ -3,12 +3,15 @@ #include "crashdumpwriter_vfs.hpp" +#include #include #include #include "purefs/vfs_subsystem.hpp" #include #include +#include +#include namespace crashdump { @@ -16,47 +19,49 @@ namespace crashdump void CrashDumpWriterVFS::openDump() { - vfs = purefs::subsystem::vfs_core(); const auto crashDumpFilePath = purefs::dir::getCrashDumpsPath() / crashDumpFileName; - + LOG_INFO("Crash dump %s preparing ...", crashDumpFilePath.c_str()); if (!rotator.rotateFile(crashDumpFilePath)) { - LOG_FATAL("Failed to rotate crash dumps."); + LOG_FATAL("Failed to rotate crash dumps errno: %i", errno); + std::abort(); } - dumpFd = vfs->open(crashDumpFilePath.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666); - - if (dumpFd < 0) { - LOG_FATAL("Failed to open crash dump file. Won't be able to save crash info."); + file = std::fopen(crashDumpFilePath.c_str(), "w"); + if (!file) { + LOG_FATAL("Failed to open crash dump file errno %i", errno); + std::abort(); } } void CrashDumpWriterVFS::saveDump() { - vfs->close(dumpFd); + 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) { - vfs->write(dumpFd, reinterpret_cast(buff), size); + if (std::fwrite(buff, sizeof(*buff), size, file) != size) { + LOG_FATAL("Unable to write crash dump errno: %i", errno); + std::abort(); + } } void CrashDumpWriterVFS::writeHalfWords(const uint16_t *buff, std::size_t size) { - for (std::size_t n = 0; n < size; ++n) { - writeBytes(reinterpret_cast(buff + n), sizeof(uint16_t)); + if (std::fwrite(buff, sizeof(*buff), size, file) != size) { + LOG_FATAL("Unable to write crash dump"); + std::abort(); } } void CrashDumpWriterVFS::writeWords(const uint32_t *buff, std::size_t size) { - for (std::size_t n = 0; n < size; ++n) { - writeBytes(reinterpret_cast(buff + n), sizeof(uint32_t)); + if (std::fwrite(buff, sizeof(*buff), size, file) != size) { + LOG_FATAL("Unable to write crash dump"); + std::abort(); } } - CrashDumpWriter &CrashDumpWriter::instance() - { - static CrashDumpWriterVFS writer; - return writer; - } - } // namespace crashdump diff --git a/board/rt1051/crashdump/crashdumpwriter_vfs.hpp b/board/rt1051/crashdump/crashdumpwriter_vfs.hpp index a2784049b63bb16f3a3ec1e4a410b8d361c2c942..c58e39e4000cdda9c4ffb7380f0120f390c33529 100644 --- a/board/rt1051/crashdump/crashdumpwriter_vfs.hpp +++ b/board/rt1051/crashdump/crashdumpwriter_vfs.hpp @@ -3,12 +3,12 @@ #pragma once -#include "crashdumpwriter.hpp" #include #include #include #include +#include namespace purefs::fs { @@ -18,23 +18,21 @@ namespace purefs::fs namespace crashdump { constexpr inline auto maxRotationFilesCount = 5; - class CrashDumpWriterVFS : public CrashDumpWriter + class CrashDumpWriterVFS { public: CrashDumpWriterVFS() : rotator{".hex"} {} - void openDump() override; - void saveDump() override; + void openDump(); + void saveDump(); - void writeBytes(const std::uint8_t *buff, std::size_t size) override; - void writeHalfWords(const std::uint16_t *buff, std::size_t size) override; - void writeWords(const std::uint32_t *buff, std::size_t size) override; + void writeBytes(const std::uint8_t *buff, std::size_t size); + void writeHalfWords(const std::uint16_t *buff, std::size_t size); + void writeWords(const std::uint32_t *buff, std::size_t size); private: utils::Rotator rotator; - int dumpFd{-1}; - - std::shared_ptr vfs; + std::FILE *file{}; }; } // namespace crashdump diff --git a/module-vfs/drivers/src/purefs/fs/filesystem_ext4.cpp b/module-vfs/drivers/src/purefs/fs/filesystem_ext4.cpp index a8b852602a332997e989fa080db68ad6b231da66..22b6328ce40c82ae54b9fb1fb197c9fbd042f48c 100644 --- a/module-vfs/drivers/src/purefs/fs/filesystem_ext4.cpp +++ b/module-vfs/drivers/src/purefs/fs/filesystem_ext4.cpp @@ -130,8 +130,12 @@ namespace purefs::fs::drivers LOG_ERROR("Unable to append volume err: %i", err); return err; } - // Test only - ext4_dmask_set(DEBUG_ALL); + /** If verbosed lwext4 debug is required please uncomment + * this line. It may cause to print a lot of messages + * especially when the ext4 journal is recovered + * on the log output device so it is disabled by default + */ + // ext4_dmask_set(DEBUG_ALL); err = ext4_device_register(bd, disk->name().c_str()); if (err) { LOG_ERROR("Unable to register device with err: %i", err); diff --git a/module-vfs/drivers/src/thirdparty/lwext4/ext4_bdev.cpp b/module-vfs/drivers/src/thirdparty/lwext4/ext4_bdev.cpp index c14cca64920dea506a6c18d8bd1232da1a428a06..3460dcb6efc878850b0197db1da240566cd273f7 100644 --- a/module-vfs/drivers/src/thirdparty/lwext4/ext4_bdev.cpp +++ b/module-vfs/drivers/src/thirdparty/lwext4/ext4_bdev.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -47,29 +48,34 @@ namespace purefs::fs::drivers::ext4::internal if (!ctx) { return -EIO; } + cpp_freertos::LockGuard _lck(ctx->mutex); auto diskmm = ctx->disk.lock(); if (!diskmm) { return -EIO; } const auto err = diskmm->write(ctx->disk_h, buf, blk_id, blk_cnt); if (err) { - LOG_ERROR("Sector write error errno: %i", err); + LOG_ERROR( + "Sector write error errno: %i on block: %u cnt: %u", err, unsigned(blk_id), unsigned(blk_cnt)); } return -err; } + int read(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id, uint32_t blk_cnt) { auto ctx = reinterpret_cast(bdev->bdif->p_user); if (!ctx) { return -EIO; } + cpp_freertos::LockGuard _lck(ctx->mutex); auto diskmm = ctx->disk.lock(); if (!diskmm) { return -EIO; } const auto err = diskmm->read(ctx->disk_h, buf, blk_id, blk_cnt); if (err) { - LOG_ERROR("Sector read error errno: %i", err); + LOG_ERROR( + "Sector read error errno: %i on block: %u cnt: %u", err, unsigned(blk_id), unsigned(blk_cnt)); } return -err; } @@ -78,6 +84,7 @@ namespace purefs::fs::drivers::ext4::internal { return 0; } + int close(struct ext4_blockdev *bdev) { return 0;