diff options
author | Vladimir Mezentsev <vladimir.mezentsev@oracle.com> | 2023-02-07 14:58:25 -0800 |
---|---|---|
committer | Vladimir Mezentsev <vladimir.mezentsev@oracle.com> | 2023-02-07 21:26:21 -0800 |
commit | e02841b095a7797aaae1b064fb4b7acc2eb8d900 (patch) | |
tree | b3c1d93dd5d448613008f0db1730cf0a4e5d985b | |
parent | 4170bc7ea846a14485e4729f1e2d707a04035c6f (diff) | |
download | gdb-e02841b095a7797aaae1b064fb4b7acc2eb8d900.zip gdb-e02841b095a7797aaae1b064fb4b7acc2eb8d900.tar.gz gdb-e02841b095a7797aaae1b064fb4b7acc2eb8d900.tar.bz2 |
gprofng: fix SIGSEGV when processing unusual dwarf
gprofng/ChangeLog
2023-02-07 Vladimir Mezentsev <vladimir.mezentsev@oracle.com>
PR gprofng/30093
* src/Dwarf.cc: add nullptr check.
* src/DwarfLib.cc: Likewise.
-rw-r--r-- | gprofng/src/Dwarf.cc | 16 | ||||
-rw-r--r-- | gprofng/src/DwarfLib.cc | 20 |
2 files changed, 22 insertions, 14 deletions
diff --git a/gprofng/src/Dwarf.cc b/gprofng/src/Dwarf.cc index 1b33ae8..5485be7 100644 --- a/gprofng/src/Dwarf.cc +++ b/gprofng/src/Dwarf.cc @@ -606,12 +606,15 @@ Dwarf::archive_Dwarf (LoadObject *lo) { mod->hdrOffset = dwrCUs->size (); DwrLineRegs *lineReg = dwrCU->get_dwrLineReg (); - dwrCU->srcFiles = new Vector<SourceFile *> (VecSize (lineReg->file_names)); - for (long i = 0, sz = VecSize (lineReg->file_names); i < sz; i++) + if (lineReg != NULL) { - char *fname = lineReg->getPath (i + 1); - SourceFile *sf = mod->findSource (fname, true); - dwrCU->srcFiles->append (sf); + dwrCU->srcFiles = new Vector<SourceFile *> (VecSize (lineReg->file_names)); + for (long i = 0, sz = VecSize (lineReg->file_names); i < sz; i++) + { + char *fname = lineReg->getPath (i + 1); + SourceFile *sf = mod->findSource (fname, true); + dwrCU->srcFiles->append (sf); + } } Dwarf_cnt ctx; @@ -986,9 +989,6 @@ DwrCU::append_Function (Dwarf_cnt *ctx) if (lineno > 0) { func->setLineFirst (lineno); - if (dwrLineReg == NULL) - dwrLineReg = new DwrLineRegs (new DwrSec (dwarf->debug_lineSec, - stmt_list_offset), comp_dir); int fileno = ((int) Dwarf_data (DW_AT_decl_file)) - 1; SourceFile *sf = ((fileno >= 0) && (fileno < VecSize (srcFiles))) ? srcFiles->get (fileno) : module->getMainSrc (); diff --git a/gprofng/src/DwarfLib.cc b/gprofng/src/DwarfLib.cc index 4f86a78..e7130a7 100644 --- a/gprofng/src/DwarfLib.cc +++ b/gprofng/src/DwarfLib.cc @@ -31,6 +31,7 @@ #include "DbeArray.h" #include "DbeSession.h" +#define NO_STMT_LIST ((uint64_t) -1) #define CASE_S(x) case x: s = (char *) #x; break static char * @@ -1557,8 +1558,11 @@ DwrLineRegs::getPath (int fn) if (*dir != '/') { // not absolute char *s = include_directories->fetch (0); - sb.append (s); - sb.append ('/'); + if (s != NULL && *s != 0) + { + sb.append (s); + sb.append ('/'); + } } sb.append (dir); sb.append ('/'); @@ -1590,7 +1594,7 @@ DwrCU::DwrCU (Dwarf *_dwarf) abbrevTable = NULL; dwrInlinedSubrs = NULL; srcFiles = NULL; - stmt_list_offset = 0; + stmt_list_offset = NO_STMT_LIST; dwrLineReg = NULL; isMemop = false; isGNU = false; @@ -1857,7 +1861,9 @@ DwrCU::parse_cu_header (LoadObject *lo) char *name = Dwarf_string (DW_AT_name); if (name == NULL) name = NTXT ("UnnamedUnit"); - stmt_list_offset = Dwarf_data (DW_AT_stmt_list); + int64_t v; + if (read_data_attr(DW_AT_stmt_list, &v) == DW_DLV_OK) + stmt_list_offset = v; comp_dir = dbe_strdup (Dwarf_string (DW_AT_comp_dir)); char *dir_name = comp_dir ? StrChr (comp_dir, ':') : NULL; char *orig_name = Dwarf_string (DW_AT_SUN_original_name); @@ -2073,6 +2079,8 @@ DwrCU::map_dwarf_lines (Module *mod) Stabs::is_fortran (mod->lang_code)); } } + if (lineReg == NULL) + return; Vector<DwrLine *> *lines = lineReg->get_lines (); Include *includes = new Include; @@ -2083,7 +2091,7 @@ DwrCU::map_dwarf_lines (Module *mod) for (long i = 0, sz = VecSize (lines); i < sz; i++) { DwrLine *dwrLine = lines->get (i); - char *filename = dwrLineReg->getPath (dwrLine->file); + char *filename = lineReg->getPath (dwrLine->file); if (filename == NULL) continue; uint64_t pc = dwrLine->address; @@ -2123,7 +2131,7 @@ DwrCU::map_dwarf_lines (Module *mod) DwrLineRegs * DwrCU::get_dwrLineReg () { - if (dwrLineReg == NULL) + if (dwrLineReg == NULL && stmt_list_offset != NO_STMT_LIST) dwrLineReg = new DwrLineRegs (new DwrSec (dwarf->debug_lineSec, stmt_list_offset), comp_dir); return dwrLineReg; |