[PATCH] Fix Ada crash with .debug_names

Tom de Vries tdevries@suse.de
Thu Apr 23 12:43:06 GMT 2020


On 21-04-2020 17:23, Tom Tromey wrote:
> PR ada/25837 points out a crash in the gdb testsuite when .debug_names
> is used.  You can reproduce like:
> 
>     runtest --target_board=cc-with-debug-names \
>         gdb.ada/big_packed_array.exp
> 
> The bug was introduced by commit e0802d599 ("Avoid copying in
> lookup_name_info").  The problem is that the return type of
> language_lookup_name changed, but in a way that didn't cause existing
> callers to trigger a compilation error.  So, the matcher cache in
> dw2_expand_symtabs_matching_symbol, which stored a "const string &",
> would end up with invalid data.
> 

Hi,

it took me a while to realize that the problem is that the changed
return type of language_lookup_name caused a std::string copy
constructor to be invoked here:
...
      name_and_matcher key {
         name_matcher,
         lookup_name_without_params.language_lookup_name (lang_e)
      };
...
creating a temporary that has the lifetime of the loop body, in other
words, it'll be destroyed at the end of the loop body scope, while still
being referenced after the loop from the std::vector where we store "key".

Perhaps the log message could be extended to clarify that bit.

Otherwise, I've tested this with target board cc-with-debug-names, and
did not spot any new FAILs.

Thanks,
- Tom

---

$ cat test.c
#include <string>
#include <vector>
#include <iostream>
#include <string.h>

struct name_and_matcher
{
#if FIX
  const char *name;
#else
  const std::string &name;
#endif

  bool operator== (const name_and_matcher &other) const
  {
    bool res;
#if FIX
    res = strcmp (name, other.name) == 0;
#else
    res = name == other.name;
#endif
    return res;
  }
};

int
main (void)
{
  std::vector<name_and_matcher> matchers;

  const char *str[] = {
    "itsy", "bitsy", "spider"
  };

  int i;
  for (i = 0; i < 3; ++i)
    {
      name_and_matcher key {
         str[i]
      };

      matchers.push_back (std::move (key));
    }

  for(std::vector<name_and_matcher>::iterator it = matchers.begin ();
      it != matchers.end(); ++it)
    std::cout << it->name << "\n";

  return 0;
}

---

$ g++ test.c -O0 -DFIX=0
$ ./a.out
spider
spider
spider

---

$ g++ test.c -O0 -DFIX=1
itsy
bitsy
spider


More information about the Gdb-patches mailing list