On Wed, 2010-08-18 at 10:59 -0700, Roland McGrath wrote:
> The actual exception came from the dwarf_data::directory_table
> constructor that takes a dwarf::directory_table. Because it tries to
> convert the const char* directory strings from dwarf_getsrcdirs to
> std::strings. But the first entry is the CU directory path which can be
> NULL. If so the copy constructor throws because it cannot convert from
> NULL to std::string.
Hmm. I didn't realize it could ever be null in practice.
What test data did this come up in? It's probably invalid data
for a CU not to have a DW_AT_comp_dir.
This is from src/ar, the third CU:
Compilation unit at offset 16127:
Version: 3, Abbreviation section offset: 1329, Address size: 8, Offset
[ 3f0a] compile_unit
producer (strp) "GNU C 4.4.4 20100726 (Red Hat 4.4.4-13)"
language (data1) ISO C99 (12)
name (strp) "/home/mark/src/elfutils/src/arlib2.c"
low_pc (addr) 0x0000000000406e84 <arlib_add_long_name>
high_pc (addr) 0x0000000000406fa6
stmt_list (data4) 2930
Note, no DW_AT_comp_dir
> But then I get in similar trouble inside the subr::equal_to
> code. Specifically the elfutils::subr::equal_to<std::basic_string<char,
> std::char_traits<char>, std::allocator<char> >, char
> instance, which will crash and burn trying to compare the empty string
> and the NULL. Still looking into that.
I think those comparisons should work like dwarf::directory_table::table_equal
and ignore the first element anyway. I did a tweak to dwarf_data to do that.
Yes, that is what I ended up doing too.
> Hints and tips for how to
> generically deal with char*/std::string in C++ code appreciated.
This is the first case and perhaps only situation where a null pointer is a
possibility. We've skipped it, so it shouldn't come up now. I think any
other case that could produce a null string pointer should in fact throw an
error. I'm not sure what other hints you are looking for.
Maybe there was some default conversion everybody uses when dealing with
std::string vs const char* where there can be NULLs. But it seems not. I
learned a lot about conversions, copy constructors and using gdb to
catch exceptions though.