diff options
Diffstat (limited to 'src/core_dump_handler/dlt_cdh_coredump.c')
-rw-r--r-- | src/core_dump_handler/dlt_cdh_coredump.c | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/src/core_dump_handler/dlt_cdh_coredump.c b/src/core_dump_handler/dlt_cdh_coredump.c new file mode 100644 index 0000000..612174b --- /dev/null +++ b/src/core_dump_handler/dlt_cdh_coredump.c @@ -0,0 +1,202 @@ +/* + * @licence app begin@ + * SPDX license identifier: MPL-2.0 + * + * Copyright (C) 2011-2015, BMW AG + * + * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. + * + * This Source Code Form is subject to the terms of the + * Mozilla Public License (MPL), v. 2.0. + * If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * For further information see http://www.genivi.org/. + * @licence end@ + */ + +/*! + * \author Magneti Marelli http://www.magnetimarelli.com + * \author Lutz Helwing <lutz_helwing@mentor.com> + * + * \copyright Copyright © 2011-2015 BMW AG. \n + * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. + * + * \file dlt_cdh_coredump.c + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <fcntl.h> +#include <syslog.h> +#include <errno.h> + +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/stat.h> + +#include "dlt_cdh.h" + +cdh_status_t read_elf_headers(proc_info_t* p_proc) +{ + int phnum = 0; + + // Read ELF header + stream_read(&p_proc->streamer, &p_proc->m_Ehdr, sizeof(p_proc->m_Ehdr)); + + // Read until PROG position + stream_move_to_offest(&p_proc->streamer, p_proc->m_Ehdr.e_phoff); + + // Read and store all program headers + p_proc->m_pPhdr = (ELF_Phdr*) malloc(sizeof(ELF_Phdr) * p_proc->m_Ehdr.e_phnum); + if (p_proc->m_pPhdr == NULL) + { + syslog(LOG_ERR, "Cannot allocate Phdr memory (%d headers)", p_proc->m_Ehdr.e_phnum); + return CDH_NOK; + } + + for (phnum = 0; phnum < p_proc->m_Ehdr.e_phnum; phnum++) + { + // Read Programm header + stream_read(&p_proc->streamer, &p_proc->m_pPhdr[phnum], sizeof(ELF_Phdr)); + } + + return CDH_OK; +} + +int getNotePageIndex(proc_info_t* p_proc) +{ + int i = 0; + + // Search PT_NOTE section + for (i = 0; i < p_proc->m_Ehdr.e_phnum; i++) + { + syslog(LOG_INFO, "==Note section prog_note:%d type:0x%X offset:0x%X size:0x%X (%dbytes)", + i, + p_proc->m_pPhdr[i].p_type, + p_proc->m_pPhdr[i].p_offset, + p_proc->m_pPhdr[i].p_filesz, + p_proc->m_pPhdr[i].p_filesz); + + if (p_proc->m_pPhdr[i].p_type == PT_NOTE) + break; + } + + return i == p_proc->m_Ehdr.e_phnum ? CDH_NOK : i; +} + +cdh_status_t read_notes(proc_info_t* p_proc) +{ + int prog_note = getNotePageIndex(p_proc); +// p_proc->m_note_page_size = 0; + p_proc->m_Nhdr = NULL; + + // note page not found, abort + if (prog_note < 0) + { + syslog(LOG_ERR, "Cannot find note header page index"); + return CDH_NOK; + } + + // Move to NOTE header position + if (stream_move_to_offest(&p_proc->streamer, p_proc->m_pPhdr[prog_note].p_offset) != CDH_OK) + { + syslog(LOG_ERR, "Cannot move to note header"); + return CDH_NOK; + } + + if ((p_proc->m_Nhdr = (char*) malloc(p_proc->m_pPhdr[prog_note].p_filesz)) == NULL) + { + syslog(LOG_ERR, "Cannot allocate Nhdr memory (note size %d bytes)", p_proc->m_pPhdr[prog_note].p_filesz); + return CDH_NOK; + } + + if (stream_read(&p_proc->streamer, p_proc->m_Nhdr, p_proc->m_pPhdr[prog_note].p_filesz) != CDH_OK) + { + syslog(LOG_ERR, "Cannot read note header"); + return CDH_NOK; + } + + p_proc->m_note_page_size = p_proc->m_pPhdr[prog_note].p_filesz; + + return CDH_OK; +} + +cdh_status_t init_coredump(proc_info_t* p_proc) +{ + if (p_proc == NULL) + return CDH_NOK; + + if (p_proc->can_create_coredump) + { + char l_dst_filename[CORE_MAX_FILENAME_LENGTH]; + + snprintf(l_dst_filename, sizeof(l_dst_filename), CORE_FILE_PATTERN, + CORE_TMP_DIRECTORY, + p_proc->timestamp, + p_proc->name, + p_proc->pid); + + stream_init(&p_proc->streamer, 0, l_dst_filename); + } + else + { + stream_init(&p_proc->streamer, 0, NULL); + } + + return CDH_OK; +} + +cdh_status_t close_coredump(proc_info_t* p_proc) +{ + stream_close(&p_proc->streamer); + + return CDH_OK; +} + +cdh_status_t treat_coredump(proc_info_t* p_proc) +{ + cdh_status_t ret = CDH_OK; + + // open src and dest files, allocate read buffer + if (init_coredump(p_proc) != CDH_OK) + { + syslog(LOG_ERR, "cannot init coredump system"); + ret = CDH_NOK; + goto finished; + } + + if (read_elf_headers(p_proc) == CDH_OK) + { + // TODO: No NOTES here leads to crash elsewhere!!! dlt_cdh_crashid.c: around line 76 + if (read_notes(p_proc) != CDH_OK) + { + syslog(LOG_ERR, "cannot read NOTES"); + ret = CDH_NOK; + goto finished; + } + } + else + { + if (read_elf_headers(p_proc) != CDH_OK) + { + syslog(LOG_ERR, "cannot read ELF header"); + ret = CDH_NOK; + goto finished; + } + } + + finished: + // In all cases, we try to finish to read/compress the coredump until the end + if (stream_finish(&p_proc->streamer) != CDH_OK) + syslog(LOG_ERR, "cannot finish coredump compression"); + + // In all cases, let's close the files + if (close_coredump(p_proc) != CDH_OK) + syslog(LOG_ERR, "cannot close coredump system"); + + return ret; +} + |