aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Mezentsev <vladimir.mezentsev@oracle.com>2023-02-07 14:58:25 -0800
committerVladimir Mezentsev <vladimir.mezentsev@oracle.com>2023-02-07 21:26:21 -0800
commite02841b095a7797aaae1b064fb4b7acc2eb8d900 (patch)
treeb3c1d93dd5d448613008f0db1730cf0a4e5d985b
parent4170bc7ea846a14485e4729f1e2d707a04035c6f (diff)
downloadgdb-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.cc16
-rw-r--r--gprofng/src/DwarfLib.cc20
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;