Skip to content

Commit

Permalink
coredump: support coredump save to block device when crash
Browse files Browse the repository at this point in the history
Signed-off-by: anjiahao <[email protected]>
  • Loading branch information
anjiahao1 authored and xiaoxiang781216 committed Dec 10, 2023
1 parent 542a555 commit 35051dd
Show file tree
Hide file tree
Showing 12 changed files with 441 additions and 71 deletions.
2 changes: 1 addition & 1 deletion Documentation/guides/coredump.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Enable Kconfig
CONFIG_ELF_COREDUMP=y /* Enable ELF Coredump */
CONFIG_BOARD_COREDUMP=y /* Enable Board Coredump, if exceptions and assertions occur, */
CONFIG_BOARD_COREDUMP_SYSLOG=y /* Enable Board Coredump, if exceptions and assertions occur, */
CONFIG_SYSTEM_COREDUMP=y /* Enable coredump in user command, which can capture the current
state of one or all threads when the system is running, the
Expand Down
23 changes: 17 additions & 6 deletions boards/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4366,30 +4366,41 @@ config BOARD_CRASHDUMP
"machine state" in a place where on the next reset can write it
to more sophisticated storage in a sane operating environment.

config BOARD_COREDUMP
bool "Enable Core Dump after assert"
config BOARD_COREDUMP_SYSLOG
bool "Enable Core dump to syslog"
default n
depends on ELF_COREDUMP
---help---
Enable to support for the dump core information after assert.
Enable put coredump to syslog when crash.

if BOARD_COREDUMP
config BOARD_COREDUMP_BLKDEV
bool "Enable Core Dump to block device"
default n
depends on ELF_COREDUMP
---help---
Enable save coredump at block device when crash.

config BOARD_COREDUMP_BLKDEV_PATH
string "Save Core Dump block device PATH"
depends on BOARD_COREDUMP_BLKDEV
---help---
Save coredump file block device path.

config BOARD_COREDUMP_FULL
bool "Core Dump all thread registers and stacks"
default y
depends on BOARD_COREDUMP_SYSLOG || BOARD_COREDUMP_BLKDEV
---help---
Enable to support for the dump all task registers and stacks.

config BOARD_COREDUMP_COMPRESSION
bool "Enable Core Dump compression"
default y
select LIBC_LZF
depends on BOARD_COREDUMP_SYSLOG || BOARD_COREDUMP_BLKDEV
---help---
Enable LZF compression algorithm for core dump content

endif # BOARD_COREDUMP

config BOARD_ENTROPY_POOL
bool "Enable Board level storing of entropy pool structure"
default n
Expand Down
2 changes: 1 addition & 1 deletion boards/arm/imx6/sabre-6quad/configs/coredump/defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_IRQBUTTONS=y
CONFIG_ARCH_LOWVECTORS=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARD_COREDUMP=y
CONFIG_BOARD_COREDUMP_SYSLOG=y
CONFIG_BOARD_LOOPSPERMSEC=99369
CONFIG_BOOT_RUNFROMSDRAM=y
CONFIG_BUILTIN=y
Expand Down
14 changes: 13 additions & 1 deletion include/nuttx/binfmt/binfmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#include <spawn.h>
#include <sys/types.h>
#include <sys/utsname.h>

#include <nuttx/sched.h>
#include <nuttx/streams.h>
Expand All @@ -38,7 +39,8 @@
* Pre-processor Definitions
****************************************************************************/

#define BINFMT_NALLOC 4
#define BINFMT_NALLOC 4
#define COREDUMP_MAGIC 0x434f5245

/****************************************************************************
* Public Types
Expand Down Expand Up @@ -138,6 +140,16 @@ struct binfmt_s
pid_t pid);
};

/* Coredump information for block header */

struct coredump_info_s
{
uint32_t magic;
struct utsname name;
time_t time;
size_t size;
};

/****************************************************************************
* Public Data
****************************************************************************/
Expand Down
30 changes: 30 additions & 0 deletions include/nuttx/memoryregion.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,34 @@ ssize_t parse_memory_region(FAR const char *format,
FAR struct memory_region_s *region,
size_t num);

/****************************************************************************
* Name: alloc_memory_region
*
* Input Parameters:
* format - The format string to parse. <start>,<end>,<flags>,...
* start - The start address of the memory region
* end - The end address of the memory region
* flags - Readable 0x1, writable 0x2, executable 0x4
* example: 0x1000,0x2000,0x1,0x2000,0x3000,0x3,0x3000,0x4000,0x7
*
* Return:
* The parsed memory region list on success; NULL on failure.
* The boundary value of the memory region is zero.
* The return value need free by caller.
*
****************************************************************************/

FAR struct memory_region_s *
alloc_memory_region(FAR const char *format);

/****************************************************************************
* Name: free_memory_region
*
* Input Parameters:
* region - The memory region list to free.
*
****************************************************************************/

void free_memory_region(FAR struct memory_region_s *region);

#endif /* __INCLUDE_MEMORYREGION_H */
74 changes: 73 additions & 1 deletion libs/libc/misc/lib_memoryregion.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
****************************************************************************/

#include <nuttx/memoryregion.h>
#include <nuttx/lib/lib.h>
#include <stdlib.h>
#include <errno.h>

Expand Down Expand Up @@ -52,11 +53,28 @@ ssize_t parse_memory_region(FAR const char *format,
FAR char *endptr;
size_t i = 0;

if (format == NULL || region == NULL || num == 0)
if (format == NULL)
{
return -EINVAL;
}

if (num == 0 || region == NULL)
{
num = 0;
while (format[i] != '\0')
{
if (format[i++] == ',')
{
num++;
}
}
}

if (region == NULL)
{
return num / 3 + 1;
}

while (*format != '\0' && i < num * 3)
{
if (i % 3 == 0)
Expand All @@ -78,3 +96,57 @@ ssize_t parse_memory_region(FAR const char *format,

return i / 3;
}

/****************************************************************************
* Name: alloc_memory_region
*
* Input Parameters:
* format - The format string to parse. <start>,<end>,<flags>,...
* start - The start address of the memory region
* end - The end address of the memory region
* flags - Readable 0x1, writable 0x2, executable 0x4
* example: 0x1000,0x2000,0x1,0x2000,0x3000,0x3,0x3000,0x4000,0x7
*
* Return:
* The parsed memory region list on success; NULL on failure.
* The boundary value of the memory region is zero.
* The return value need free by caller.
*
****************************************************************************/

FAR struct memory_region_s *
alloc_memory_region(FAR const char *format)
{
FAR struct memory_region_s *region;
ssize_t num = parse_memory_region(format, NULL, 0);

if (num < 0)
{
return NULL;
}

region = lib_zalloc(sizeof(struct memory_region_s) * (num + 1));
if (region == NULL)
{
return NULL;
}

parse_memory_region(format, region, num);
return region;
}

/****************************************************************************
* Name: free_memory_region
*
* Input Parameters:
* region - The memory region list to free.
*
****************************************************************************/

void free_memory_region(FAR struct memory_region_s *region)
{
if (region != NULL)
{
lib_free(region);
}
}
6 changes: 6 additions & 0 deletions sched/init/nx_bringup.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "sched/sched.h"
#include "wqueue/wqueue.h"
#include "init/init.h"
#include "misc/coredump.h"

/****************************************************************************
* Pre-processor Definitions
Expand Down Expand Up @@ -248,6 +249,11 @@ static inline void nx_start_application(void)
board_late_initialize();
#endif

#if defined(CONFIG_BOARD_COREDUMP_SYSLOG) || \
defined(CONFIG_BOARD_COREDUMP_BLKDEV)
coredump_initialize();
#endif

posix_spawnattr_init(&attr);
attr.priority = CONFIG_INIT_PRIORITY;
attr.stacksize = CONFIG_INIT_STACKSIZE;
Expand Down
4 changes: 4 additions & 0 deletions sched/misc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,8 @@ if(CONFIG_DUMP_ON_EXIT)
list(APPEND SRCS dump.c)
endif()

if(CONFIG_BOARD_COREDUMP_SYSLOG OR CONFIG_BOARD_COREDUMP_BLKDEV)
list(APPEND SRCS coredump.c)
endif()

target_sources(sched PRIVATE ${SRCS})
4 changes: 4 additions & 0 deletions sched/misc/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ ifeq ($(CONFIG_DUMP_ON_EXIT),y)
CSRCS += dump.c
endif

ifneq ($(CONFIG_BOARD_COREDUMP_SYSLOG)$(CONFIG_BOARD_COREDUMP_BLKDEV),)
CSRCS += coredump.c
endif

# Include init build support

DEPPATH += --dep-path misc
Expand Down
67 changes: 6 additions & 61 deletions sched/misc/assert.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#include <nuttx/config.h>

#include <nuttx/arch.h>
#include <nuttx/binfmt/binfmt.h>
#include <nuttx/board.h>
#include <nuttx/irq.h>
#include <nuttx/tls.h>
Expand All @@ -47,6 +46,7 @@
#include "irq/irq.h"
#include "sched/sched.h"
#include "group/group.h"
#include "misc/coredump.h"

/****************************************************************************
* Pre-processor Definitions
Expand Down Expand Up @@ -77,15 +77,6 @@
****************************************************************************/

static uintptr_t g_last_regs[XCPTCONTEXT_REGS] aligned_data(16);

#ifdef CONFIG_BOARD_COREDUMP
static struct lib_syslogstream_s g_syslogstream;
static struct lib_hexdumpstream_s g_hexstream;
# ifdef CONFIG_BOARD_COREDUMP_COMPRESSION
static struct lib_lzfoutstream_s g_lzfstream;
# endif
#endif

static FAR const char *g_policy[4] =
{
"FIFO", "RR", "SPORADIC"
Expand Down Expand Up @@ -481,53 +472,6 @@ static void dump_tasks(void)
#endif
}

/****************************************************************************
* Name: dump_core
****************************************************************************/

#ifdef CONFIG_BOARD_COREDUMP
static void dump_core(pid_t pid)
{
FAR void *stream;
int logmask;

logmask = setlogmask(LOG_ALERT);

_alert("Start coredump:\n");

/* Initialize hex output stream */

lib_syslogstream(&g_syslogstream, LOG_EMERG);

stream = &g_syslogstream;

lib_hexdumpstream(&g_hexstream, stream);

stream = &g_hexstream;

# ifdef CONFIG_BOARD_COREDUMP_COMPRESSION

/* Initialize LZF compression stream */

lib_lzfoutstream(&g_lzfstream, stream);
stream = &g_lzfstream;

# endif

/* Do core dump */

core_dump(NULL, stream, pid);

# ifdef CONFIG_BOARD_COREDUMP_COMPRESSION
_alert("Finish coredump (Compression Enabled).\n");
# else
_alert("Finish coredump.\n");
# endif

setlogmask(logmask);
}
#endif

/****************************************************************************
* Name: dump_deadlock
****************************************************************************/
Expand Down Expand Up @@ -681,16 +625,17 @@ void _assert(FAR const char *filename, int linenum,

#ifdef CONFIG_BOARD_CRASHDUMP
board_crashdump(up_getsp(), rtcb, filename, linenum, msg, regs);
#endif

#elif defined(CONFIG_BOARD_COREDUMP)
#if defined(CONFIG_BOARD_COREDUMP_SYSLOG) || \
defined(CONFIG_BOARD_COREDUMP_BLKDEV)
/* Dump core information */

# ifdef CONFIG_BOARD_COREDUMP_FULL
dump_core(INVALID_PROCESS_ID);
coredump_dump(INVALID_PROCESS_ID);
# else
dump_core(rtcb->pid);
coredump_dump(rtcb->pid);
# endif

#endif

/* Flush any buffered SYSLOG data */
Expand Down
Loading

0 comments on commit 35051dd

Please sign in to comment.