From 4de86e6545480af847b5eb6b58d43f044e449fc5 Mon Sep 17 00:00:00 2001 From: Sunmin Lee Date: Tue, 20 Dec 2016 18:41:00 +0900 Subject: [PATCH] crash-stack: deprecate corefile option crash-stack should be able to generate call stack using pid only. (Generating corefile causes sluggish issue) Change-Id: Ie9e74494b966838d1dd6548424d51bfd2df4c1e0 --- src/crash-stack/crash-stack.c | 259 ++---------------------------------------- 1 file changed, 10 insertions(+), 249 deletions(-) diff --git a/src/crash-stack/crash-stack.c b/src/crash-stack/crash-stack.c index 63a2b4a..ea4dbc5 100644 --- a/src/crash-stack/crash-stack.c +++ b/src/crash-stack/crash-stack.c @@ -48,12 +48,6 @@ #include #include -/* - * In case the program is compiled with core dumps, the license may switch to GPL2. - */ -#ifdef WITH_CORE_DUMP -#include -#endif #define BUF_SIZE (BUFSIZ) #define HEXA 16 @@ -426,53 +420,6 @@ static Dwfl *__open_dwfl_with_pid(pid_t pid, pid_t tid) } /** - * @brief Opens libdwfl for using with core dump file - * - * @remarks This function will open core file regardless of WITH_CORE_DUMP setting. - * It may help with detecting issues with using dwfl even without support - * for dumps. - * - * @param core elf handler for the core dump file - * @param core_file_name name of the core file; needed only for diagnostics - * @return Dwfl handle - */ -static Dwfl *__open_dwfl_with_core(Elf *core, const char *core_file_name) -{ - static const Dwfl_Callbacks core_callbacks = { - .find_elf = dwfl_build_id_find_elf, - .find_debuginfo = dwfl_standard_find_debuginfo, - .section_address = NULL, - .debuginfo_path = NULL - }; - - Dwfl *dwfl = dwfl_begin(&core_callbacks); - if (dwfl == NULL) { - fprintf(errfile, "%s : Can't start dwfl (%s)\n", core_file_name, dwfl_errmsg(-1)); - return NULL; - } - -#if _ELFUTILS_PREREQ(0,158) - if (dwfl_core_file_report(dwfl, core, NULL) < 0) -#else - if (dwfl_core_file_report(dwfl, core) < 0) -#endif - { - fprintf(errfile, "%s : dwfl report failed (%s)\n", core_file_name, dwfl_errmsg(-1)); - dwfl_end(dwfl); - return NULL; - } - -#if _ELFUTILS_PREREQ(0,158) - if (dwfl_core_file_attach(dwfl, core) < 0) { - fprintf(errfile, "%s : dwfl attach failed (%s)\n", core_file_name, dwfl_errmsg(-1)); - dwfl_end(dwfl); - return NULL; - } -#endif - return dwfl; -} - -/** * @brief Gets registers information for live process * * @param pid pid of the live process @@ -540,163 +487,6 @@ static int __get_signal_ptrace(pid_t pid) return 0; } -#ifdef WITH_CORE_DUMP -/** - * @brief Helper function for updating mappings. - * - * @remarks Old versions of libelf not always extract full information about modules. - * For such cases we maintain mappings for every module. Those mappings - * may be updated while reading notes from core file. - * - * @param mappings mappings database - * @param mapping_start address of the mapped start of the module; module is identified - * by mapping_start - * @param mapping_end address of the end of the module; needed to compute module boundaries - * @param offset offset within core file - unused - * @param name file name of the module - */ -static void __updateMapping(Mappings *mappings, uint64_t mapping_start, uint64_t mapping_end, - uint64_t offset, const char *name) -{ - int i; - for (i = 0; i < mappings->elems; i++) { - if (mappings->tab[i].m_start == mapping_start) { - mappings->tab[i].m_end = mapping_end; - mappings->tab[i].m_name = name; - mappings->tab[i].m_offset = offset; - mappings->tab[i].m_fd = open(name, O_RDONLY); - mappings->tab[i].m_elf = elf_begin(mappings->tab[i].m_fd, ELF_C_READ_MMAP, NULL); - return; - } - } -} -#endif - -/** - * @brief Gets registers from core dump - * - * @param core ELF handler for the core dump file - * @param core_file_name name of the core file; needed only for diagnostics - * @param mappings mappings database - * @return notes handler, NULL on error - */ -static Elf_Data *__get_registers_core(Elf *core, const char *core_file_name, Mappings *mappings) -{ - Elf_Data *notes = NULL; - /* The part below uses libebl. In case WITH_CORE_DUMP is enabled, the license - * may switch to GPL2. - */ -#ifdef WITH_CORE_DUMP - GElf_Phdr mem; - GElf_Phdr *phdr = gelf_getphdr(core, 0, &mem); - - if (phdr == NULL || phdr->p_type != PT_NOTE) { - fprintf(errfile, "%s : Missing note section at the first position in core file\n", - core_file_name); - return NULL; - } - - notes = elf_getdata_rawchunk(core, phdr->p_offset, phdr->p_filesz, ELF_T_NHDR); - if (notes == NULL) { - fprintf(errfile, "%s : error getting notes (%s)\n", core_file_name, dwfl_errmsg(-1)); - return NULL; - } - - Ebl *ebl = ebl_openbackend(core); - if (ebl == NULL) { - fprintf(errfile, "%s : Can't initialize ebl\n", core_file_name); - return NULL; - } - - GElf_Nhdr nhdr; - size_t name_pos; - size_t desc_pos; - size_t pos = 0; - size_t new_pos = 0; - int got_regs = 0; - /* registers should be in the first note! */ - while ((new_pos = gelf_getnote(notes, pos, &nhdr, &name_pos, &desc_pos)) > 0) { - if (nhdr.n_type == NT_PRSTATUS && !got_regs) { - GElf_Word regs_offset; - size_t nregloc; - const Ebl_Register_Location *reglocs; - size_t nitems; - const Ebl_Core_Item *items; - - got_regs = 1; - - if (0 == ebl_core_note(ebl, &nhdr, "CORE", ®s_offset, &nregloc, - ®locs, &nitems, &items)) { - fprintf(errfile, - "%s : error parsing notes (built with different build of libebl?)\n", - core_file_name); - return NULL; - } - - const char *regs_location = (const char *)(notes->d_buf) + pos + desc_pos - + regs_offset; - unsigned i; - - for (i = 0; i < nregloc; i++) { - const char *register_location = regs_location + reglocs[i].offset; - int regnum; - for (regnum = reglocs[i].regno; - regnum < reglocs[i].regno + reglocs[i].count; - regnum++) { - char regname[5]; - int bits, type; - const char *prefix = 0; - const char *setname = 0; - - ssize_t ret = ebl_register_info(ebl, regnum, regname, - sizeof(regname), &prefix, &setname, - &bits, &type); - if (ret < 0) { - fprintf(errfile, "%s : can't get register info\n", core_file_name); - return NULL; - } - void *place_for_reg_value = _get_place_for_register_value(regname, regnum); - - if (place_for_reg_value != NULL) - __get_value(core, register_location, bits, place_for_reg_value); - - register_location += bits / 8 + reglocs[i].pad; - } - } - } else if (nhdr.n_type == NT_FILE) { - uint64_t values_cnt = 0, page_size = 0; - const char *values; - const char *filenames; - size_t addr_size = 0; - - __parse_note_file(core, notes->d_buf + desc_pos, &values_cnt, &page_size, - &addr_size, &values, &filenames); - - int ii; - /* First: triplets of - * count = values_cnt - * Then the names of files. - */ - for (ii = 0; ii < values_cnt; ii++) { - uint64_t mapping_start = 0, mapping_end = 0, offset_in_pages = 0; - const char *item = values + 3 * addr_size * ii; - - __get_mapping_item(core, addr_size, item, &mapping_start, &mapping_end, - &offset_in_pages); - __updateMapping(mappings, mapping_start, mapping_end, - offset_in_pages*page_size, filenames); - filenames += strlen(filenames)+1; - } - } - pos = new_pos; - } - ebl_closebackend(ebl); -#else - fprintf(errfile, "Configured without support for core dump files\n"); -#endif - return notes; -} - /** * @brief Resolves procedure and module names using libdwfl * @@ -1203,8 +993,6 @@ int main(int argc, char **argv) pid_t pid = 0; pid_t tid = 0; - const char *core_file_name; - prctl(PR_SET_DUMPABLE, 0); while ((c = getopt_long_only(argc, argv, "", opts, NULL)) != -1) { @@ -1229,39 +1017,20 @@ int main(int argc, char **argv) if (tid == 0) tid = pid; - core_file_name = argv[optind]; argc -= optind; elf_version(EV_CURRENT); /* First, prepare dwfl and modules */ - Elf *core = NULL; - int core_fd = -1; Dwfl *dwfl = NULL; if (pid > 1) dwfl = __open_dwfl_with_pid(pid, tid); else { - if (argc != 1) { - fprintf(errfile, - "Usage: %s [--output file] [--erroutput file] [--pid [--tid ] | ]\n", - argv[0]); - return 1; - } - - core_fd = open(core_file_name, O_RDONLY); - if (core_fd < 0) { - perror(core_file_name); - return 2; - } - - core = elf_begin(core_fd, ELF_C_READ_MMAP, NULL); - if (core == NULL) { - fprintf(errfile, "%s : Can't open ELF (%s)\n", core_file_name, elf_errmsg(-1)); - return 3; - } - - dwfl = __open_dwfl_with_core(core, core_file_name); + fprintf(errfile, + "Usage: %s [--output file] [--erroutput file] [--pid [--tid ]]\n", + argv[0]); + return 1; } if (NULL == dwfl) @@ -1277,25 +1046,19 @@ int main(int argc, char **argv) __crash_stack_print_exe(outputfile, pid); /* Now, get registers */ - if (pid > 1) { - if (-1 == __get_signal_ptrace(pid)) - return 4444; - if (-1 == __get_registers_ptrace(tid)) - return 3333; - } else { - notes = __get_registers_core(core, core_file_name, &mappings); - if (NULL == notes) - return 2222; - } + if (-1 == __get_signal_ptrace(pid)) + return 4444; + if (-1 == __get_registers_ptrace(tid)) + return 3333; /* Unwind call stack */ Callstack callstack; callstack_constructor(&callstack); - _create_crash_stack(dwfl, core, tid, &mappings, &callstack); + _create_crash_stack(dwfl, NULL, tid, &mappings, &callstack); size_t it; for (it = 0; it != callstack.elems; ++it) - __resolve_symbols(&callstack.proc[it], dwfl, core, notes); + __resolve_symbols(&callstack.proc[it], dwfl, NULL, notes); /* Print registers */ _crash_stack_print_regs(outputfile); @@ -1316,8 +1079,6 @@ int main(int argc, char **argv) callstack_destructor(&callstack); dwfl_report_end(dwfl, NULL, NULL); dwfl_end(dwfl); - if (NULL != core) elf_end(core); - if (-1 != core_fd) close(core_fd); return 0; } -- 2.7.4