crash-stack: deprecate corefile option 80/106080/3
authorSunmin Lee <sunm.lee@samsung.com>
Tue, 20 Dec 2016 09:41:00 +0000 (18:41 +0900)
committerSunmin Lee <sunm.lee@samsung.com>
Tue, 20 Dec 2016 11:27:04 +0000 (20:27 +0900)
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

index 63a2b4a..ea4dbc5 100644 (file)
 
 #include <elfutils/version.h>
 #include <elfutils/libdwfl.h>
-/*
- * In case the program is compiled with core dumps, the license may switch to GPL2.
- */
-#ifdef WITH_CORE_DUMP
-#include <elfutils/libebl.h>
-#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", &regs_offset, &nregloc,
-                                               &reglocs, &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 <mapping-start> <mapping-end> <offset-in-pages>
-                        *     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 <pid> [--tid <tid>] | <core-file>]\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 <pid> [--tid <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;
 }