summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSunmin Lee <sunm.lee@samsung.com>2016-12-20 18:41:00 +0900
committerSunmin Lee <sunm.lee@samsung.com>2016-12-20 20:27:04 +0900
commit4de86e6545480af847b5eb6b58d43f044e449fc5 (patch)
treed29490d4ed4d3cbb7d062b6a7c22b0c441502b47 /src
parentb42ab743f0bf4695b894b27018a17620ad706e8e (diff)
downloadcrash-worker-4de86e6545480af847b5eb6b58d43f044e449fc5.tar.gz
crash-worker-4de86e6545480af847b5eb6b58d43f044e449fc5.tar.bz2
crash-worker-4de86e6545480af847b5eb6b58d43f044e449fc5.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/crash-stack/crash-stack.c259
1 files 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 <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;
}