coredump: support coredump save to block device when crash
Signed-off-by: anjiahao <anjiahao@xiaomi.com>
This commit is contained in:
parent
542a5555d3
commit
35051dd715
@ -20,7 +20,7 @@ Enable Kconfig
|
|||||||
|
|
||||||
CONFIG_ELF_COREDUMP=y /* Enable ELF Coredump */
|
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
|
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
|
state of one or all threads when the system is running, the
|
||||||
|
@ -4366,18 +4366,30 @@ config BOARD_CRASHDUMP
|
|||||||
"machine state" in a place where on the next reset can write it
|
"machine state" in a place where on the next reset can write it
|
||||||
to more sophisticated storage in a sane operating environment.
|
to more sophisticated storage in a sane operating environment.
|
||||||
|
|
||||||
config BOARD_COREDUMP
|
config BOARD_COREDUMP_SYSLOG
|
||||||
bool "Enable Core Dump after assert"
|
bool "Enable Core dump to syslog"
|
||||||
default n
|
default n
|
||||||
depends on ELF_COREDUMP
|
depends on ELF_COREDUMP
|
||||||
---help---
|
---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
|
config BOARD_COREDUMP_FULL
|
||||||
bool "Core Dump all thread registers and stacks"
|
bool "Core Dump all thread registers and stacks"
|
||||||
default y
|
default y
|
||||||
|
depends on BOARD_COREDUMP_SYSLOG || BOARD_COREDUMP_BLKDEV
|
||||||
---help---
|
---help---
|
||||||
Enable to support for the dump all task registers and stacks.
|
Enable to support for the dump all task registers and stacks.
|
||||||
|
|
||||||
@ -4385,11 +4397,10 @@ config BOARD_COREDUMP_COMPRESSION
|
|||||||
bool "Enable Core Dump compression"
|
bool "Enable Core Dump compression"
|
||||||
default y
|
default y
|
||||||
select LIBC_LZF
|
select LIBC_LZF
|
||||||
|
depends on BOARD_COREDUMP_SYSLOG || BOARD_COREDUMP_BLKDEV
|
||||||
---help---
|
---help---
|
||||||
Enable LZF compression algorithm for core dump content
|
Enable LZF compression algorithm for core dump content
|
||||||
|
|
||||||
endif # BOARD_COREDUMP
|
|
||||||
|
|
||||||
config BOARD_ENTROPY_POOL
|
config BOARD_ENTROPY_POOL
|
||||||
bool "Enable Board level storing of entropy pool structure"
|
bool "Enable Board level storing of entropy pool structure"
|
||||||
default n
|
default n
|
||||||
|
@ -17,7 +17,7 @@ CONFIG_ARCH_INTERRUPTSTACK=2048
|
|||||||
CONFIG_ARCH_IRQBUTTONS=y
|
CONFIG_ARCH_IRQBUTTONS=y
|
||||||
CONFIG_ARCH_LOWVECTORS=y
|
CONFIG_ARCH_LOWVECTORS=y
|
||||||
CONFIG_ARCH_STACKDUMP=y
|
CONFIG_ARCH_STACKDUMP=y
|
||||||
CONFIG_BOARD_COREDUMP=y
|
CONFIG_BOARD_COREDUMP_SYSLOG=y
|
||||||
CONFIG_BOARD_LOOPSPERMSEC=99369
|
CONFIG_BOARD_LOOPSPERMSEC=99369
|
||||||
CONFIG_BOOT_RUNFROMSDRAM=y
|
CONFIG_BOOT_RUNFROMSDRAM=y
|
||||||
CONFIG_BUILTIN=y
|
CONFIG_BUILTIN=y
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include <spawn.h>
|
#include <spawn.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
#include <nuttx/sched.h>
|
#include <nuttx/sched.h>
|
||||||
#include <nuttx/streams.h>
|
#include <nuttx/streams.h>
|
||||||
@ -38,7 +39,8 @@
|
|||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define BINFMT_NALLOC 4
|
#define BINFMT_NALLOC 4
|
||||||
|
#define COREDUMP_MAGIC 0x434f5245
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
@ -138,6 +140,16 @@ struct binfmt_s
|
|||||||
pid_t pid);
|
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
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -63,4 +63,34 @@ ssize_t parse_memory_region(FAR const char *format,
|
|||||||
FAR struct memory_region_s *region,
|
FAR struct memory_region_s *region,
|
||||||
size_t num);
|
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 */
|
#endif /* __INCLUDE_MEMORYREGION_H */
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/memoryregion.h>
|
#include <nuttx/memoryregion.h>
|
||||||
|
#include <nuttx/lib/lib.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
@ -52,11 +53,28 @@ ssize_t parse_memory_region(FAR const char *format,
|
|||||||
FAR char *endptr;
|
FAR char *endptr;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
if (format == NULL || region == NULL || num == 0)
|
if (format == NULL)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
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)
|
while (*format != '\0' && i < num * 3)
|
||||||
{
|
{
|
||||||
if (i % 3 == 0)
|
if (i % 3 == 0)
|
||||||
@ -78,3 +96,57 @@ ssize_t parse_memory_region(FAR const char *format,
|
|||||||
|
|
||||||
return i / 3;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
#include "wqueue/wqueue.h"
|
#include "wqueue/wqueue.h"
|
||||||
#include "init/init.h"
|
#include "init/init.h"
|
||||||
|
#include "misc/coredump.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
@ -248,6 +249,11 @@ static inline void nx_start_application(void)
|
|||||||
board_late_initialize();
|
board_late_initialize();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_BOARD_COREDUMP_SYSLOG) || \
|
||||||
|
defined(CONFIG_BOARD_COREDUMP_BLKDEV)
|
||||||
|
coredump_initialize();
|
||||||
|
#endif
|
||||||
|
|
||||||
posix_spawnattr_init(&attr);
|
posix_spawnattr_init(&attr);
|
||||||
attr.priority = CONFIG_INIT_PRIORITY;
|
attr.priority = CONFIG_INIT_PRIORITY;
|
||||||
attr.stacksize = CONFIG_INIT_STACKSIZE;
|
attr.stacksize = CONFIG_INIT_STACKSIZE;
|
||||||
|
@ -28,4 +28,8 @@ if(CONFIG_DUMP_ON_EXIT)
|
|||||||
list(APPEND SRCS dump.c)
|
list(APPEND SRCS dump.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_BOARD_COREDUMP_SYSLOG OR CONFIG_BOARD_COREDUMP_BLKDEV)
|
||||||
|
list(APPEND SRCS coredump.c)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_sources(sched PRIVATE ${SRCS})
|
target_sources(sched PRIVATE ${SRCS})
|
||||||
|
@ -28,6 +28,10 @@ ifeq ($(CONFIG_DUMP_ON_EXIT),y)
|
|||||||
CSRCS += dump.c
|
CSRCS += dump.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq ($(CONFIG_BOARD_COREDUMP_SYSLOG)$(CONFIG_BOARD_COREDUMP_BLKDEV),)
|
||||||
|
CSRCS += coredump.c
|
||||||
|
endif
|
||||||
|
|
||||||
# Include init build support
|
# Include init build support
|
||||||
|
|
||||||
DEPPATH += --dep-path misc
|
DEPPATH += --dep-path misc
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
#include <nuttx/binfmt/binfmt.h>
|
|
||||||
#include <nuttx/board.h>
|
#include <nuttx/board.h>
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/tls.h>
|
#include <nuttx/tls.h>
|
||||||
@ -47,6 +46,7 @@
|
|||||||
#include "irq/irq.h"
|
#include "irq/irq.h"
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
#include "group/group.h"
|
#include "group/group.h"
|
||||||
|
#include "misc/coredump.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
@ -77,15 +77,6 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static uintptr_t g_last_regs[XCPTCONTEXT_REGS] aligned_data(16);
|
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] =
|
static FAR const char *g_policy[4] =
|
||||||
{
|
{
|
||||||
"FIFO", "RR", "SPORADIC"
|
"FIFO", "RR", "SPORADIC"
|
||||||
@ -481,53 +472,6 @@ static void dump_tasks(void)
|
|||||||
#endif
|
#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
|
* Name: dump_deadlock
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -681,16 +625,17 @@ void _assert(FAR const char *filename, int linenum,
|
|||||||
|
|
||||||
#ifdef CONFIG_BOARD_CRASHDUMP
|
#ifdef CONFIG_BOARD_CRASHDUMP
|
||||||
board_crashdump(up_getsp(), rtcb, filename, linenum, msg, regs);
|
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 */
|
/* Dump core information */
|
||||||
|
|
||||||
# ifdef CONFIG_BOARD_COREDUMP_FULL
|
# ifdef CONFIG_BOARD_COREDUMP_FULL
|
||||||
dump_core(INVALID_PROCESS_ID);
|
coredump_dump(INVALID_PROCESS_ID);
|
||||||
# else
|
# else
|
||||||
dump_core(rtcb->pid);
|
coredump_dump(rtcb->pid);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Flush any buffered SYSLOG data */
|
/* Flush any buffered SYSLOG data */
|
||||||
|
228
sched/misc/coredump.c
Normal file
228
sched/misc/coredump.c
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* sched/misc/coredump.c
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/binfmt/binfmt.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include "misc/coredump.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_BOARD_COREDUMP_COMPRESSION
|
||||||
|
static struct lib_lzfoutstream_s g_lzfstream;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BOARD_COREDUMP_SYSLOG
|
||||||
|
static struct lib_syslogstream_s g_syslogstream;
|
||||||
|
static struct lib_hexdumpstream_s g_hexstream;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BOARD_COREDUMP_BLKDEV
|
||||||
|
static struct lib_blkoutstream_s g_blockstream;
|
||||||
|
static unsigned char *g_blockinfo;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct memory_region_s *g_regions;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: coredump_dump_syslog
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Put coredump to block device.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_BOARD_COREDUMP_SYSLOG
|
||||||
|
static void coredump_dump_syslog(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(g_regions, stream, pid);
|
||||||
|
|
||||||
|
# ifdef CONFIG_BOARD_COREDUMP_COMPRESSION
|
||||||
|
_alert("Finish coredump (Compression Enabled).\n");
|
||||||
|
# else
|
||||||
|
_alert("Finish coredump.\n");
|
||||||
|
# endif
|
||||||
|
|
||||||
|
setlogmask(logmask);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: coredump_dump_blkdev
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Save coredump to block device.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_BOARD_COREDUMP_BLKDEV
|
||||||
|
static void coredump_dump_blkdev(pid_t pid)
|
||||||
|
{
|
||||||
|
FAR void *stream = &g_blockstream;
|
||||||
|
FAR struct coredump_info_s *info;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (g_blockstream.inode == NULL)
|
||||||
|
{
|
||||||
|
_alert("Coredump Device Not Found\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = g_blockstream.inode->u.i_bops->read(g_blockstream.inode,
|
||||||
|
g_blockinfo, g_blockstream.geo.geo_nsectors - 1, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
_alert("Coredump Device Read Fail\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
info = (FAR struct coredump_info_s *)g_blockinfo;
|
||||||
|
if (info->magic == COREDUMP_MAGIC)
|
||||||
|
{
|
||||||
|
_alert("Coredump Device Already Used\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_BOARD_COREDUMP_COMPRESSION
|
||||||
|
lib_lzfoutstream(&g_lzfstream,
|
||||||
|
(FAR struct lib_outstream_s *)&g_blockstream);
|
||||||
|
stream = &g_lzfstream;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = core_dump(g_regions, stream, pid);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
_alert("Coredump Fail\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->magic = COREDUMP_MAGIC;
|
||||||
|
info->size = g_blockstream.common.nput;
|
||||||
|
info->time = time(NULL);
|
||||||
|
uname(&info->name);
|
||||||
|
g_blockstream.inode->u.i_bops->write(g_blockstream.inode,
|
||||||
|
(FAR void *)info, g_blockstream.geo.geo_nsectors - 1, 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: coredump_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize the coredump facility. Called once and only from
|
||||||
|
* nx_start_application.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int coredump_initialize(void)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (CONFIG_BOARD_MEMORY_RANGE[0] != '\0')
|
||||||
|
{
|
||||||
|
g_regions = alloc_memory_region(CONFIG_BOARD_MEMORY_RANGE);
|
||||||
|
if (g_regions == NULL)
|
||||||
|
{
|
||||||
|
_alert("Memory Region Alloc Fail\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_BOARD_COREDUMP_BLKDEV
|
||||||
|
ret = lib_blkoutstream_open(&g_blockstream,
|
||||||
|
CONFIG_BOARD_COREDUMP_BLKDEV_PATH);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
_alert("%s Coredump Device Not Found\n",
|
||||||
|
CONFIG_BOARD_COREDUMP_BLKDEV_PATH);
|
||||||
|
free_memory_region(g_regions);
|
||||||
|
g_regions = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_blockinfo = kmm_malloc(g_blockstream.geo.geo_sectorsize);
|
||||||
|
if (g_blockinfo == NULL)
|
||||||
|
{
|
||||||
|
_alert("Coredump Device Memory Alloc Fail\n");
|
||||||
|
free_memory_region(g_regions);
|
||||||
|
g_regions = NULL;
|
||||||
|
lib_blkoutstream_close(&g_blockstream);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: coredump_dump
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Do coredump of the task specified by pid.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* pid - The task/thread ID of the thread to dump
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void coredump_dump(pid_t pid)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_BOARD_COREDUMP_SYSLOG
|
||||||
|
coredump_dump_syslog(pid);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BOARD_COREDUMP_BLKDEV
|
||||||
|
coredump_dump_blkdev(pid);
|
||||||
|
#endif
|
||||||
|
}
|
58
sched/misc/coredump.h
Normal file
58
sched/misc/coredump.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* sched/misc/coredump.h
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __SCHED_MISC_COREDUMP_H
|
||||||
|
#define __SCHED_MISC_COREDUMP_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: coredump_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize the coredump facility. Called once and only from
|
||||||
|
* nx_start_application.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int coredump_initialize(void);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: coredump_dump
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Do coredump of the task specified by pid.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* pid - The task/thread ID of the thread to dump
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void coredump_dump(pid_t pid);
|
||||||
|
|
||||||
|
#endif /* __SCHED_MISC_COREDUMP_H */
|
Loading…
Reference in New Issue
Block a user