]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb: don't call macro_bcache with nullptr
authorSimon Marchi <simon.marchi@efficios.com>
Tue, 30 Jul 2024 19:24:58 +0000 (19:24 +0000)
committerSimon Marchi <simon.marchi@efficios.com>
Tue, 30 Jul 2024 19:30:42 +0000 (15:30 -0400)
Since commit b1da98a74656 ("gdb: remove use of alloca in
new_macro_definition"), if cached_argv is empty, we call macro_bcache
with a nullptr data.  This ends up caught by UBSan deep down in the
bcache code:

    $ ./gdb -nx -q --data-directory=data-directory  /home/smarchi/build/binutils-gdb/gdb/testsuite/outputs/gdb.base/macscp/macscp -readnow
    Reading symbols from /home/smarchi/build/binutils-gdb/gdb/testsuite/outputs/gdb.base/macscp/macscp...
    Expanding full symbols from /home/smarchi/build/binutils-gdb/gdb/testsuite/outputs/gdb.base/macscp/macscp...
    /home/smarchi/src/binutils-gdb/gdb/bcache.c:195:12: runtime error: null pointer passed as argument 2, which is declared to never be null

The backtrace:

    #1  0x00007ffff619a05d in __ubsan::__ubsan_handle_nonnull_arg_abort (Data=<optimized out>) at ../../../../src/libsanitizer/ubsan/ubsan_handlers.cpp:750
    #2  0x000055556337fba2 in gdb::bcache::insert (this=0x62d0000c8458, addr=0x0, length=0, added=0x0) at /home/smarchi/src/binutils-gdb/gdb/bcache.c:195
    #3  0x0000555564b49222 in gdb::bcache::insert<char const*, void> (this=0x62d0000c8458, addr=0x0, length=0, added=0x0) at /home/smarchi/src/binutils-gdb/gdb/bcache.h:158
    #4  0x0000555564b481fa in macro_bcache<char const*> (t=0x62100007ae70, addr=0x0, len=0) at /home/smarchi/src/binutils-gdb/gdb/macrotab.c:117
    #5  0x0000555564b42b4a in new_macro_definition (t=0x62100007ae70, kind=macro_function_like, special_kind=macro_ordinary, argv=std::__debug::vector of length 0, capacity 0, replacement=0x62a00003af3a "__builtin_va_arg_pack ()") at /home/smarchi/src/binutils-gdb/gdb/macrotab.c:573
    #6  0x0000555564b44674 in macro_define_internal (source=0x6210000ab9e0, line=469, name=0x7fffffffa710 "__va_arg_pack", kind=macro_function_like, special_kind=macro_ordinary, argv=std::__debug::vector of length 0, capacity 0, replacement=0x62a00003af3a "__builtin_va_arg_pack ()") at /home/smarchi/src/binutils-gdb/gdb/macrotab.c:777
    #7  0x0000555564b44ae2 in macro_define_function (source=0x6210000ab9e0, line=469, name=0x7fffffffa710 "__va_arg_pack", argv=std::__debug::vector of length 0, capacity 0, replacement=0x62a00003af3a "__builtin_va_arg_pack ()") at /home/smarchi/src/binutils-gdb/gdb/macrotab.c:816
    #8  0x0000555563f62fc8 in parse_macro_definition (file=0x6210000ab9e0, line=469, body=0x62a00003af2a "__va_arg_pack() __builtin_va_arg_pack ()") at /home/smarchi/src/binutils-gdb/gdb/dwarf2/macro.c:203

This can be reproduced by running gdb.base/macscp.exp.  Avoid calling
macro_bcache if the macro doesn't have any arguments.

Change-Id: I33b5a7c3b3a93d5adba98983fcaae9c8522c383d

gdb/macrotab.c

index 21ec1522a900e16ede297e9c6d217e3f849678f1..37ae0f233c539189534cd67a7989f63ab7efc250 100644 (file)
@@ -564,14 +564,17 @@ new_macro_definition (macro_table *t, macro_kind kind,
       d->argc = argv.size ();
 
       /* Bcache all the arguments.  */
-      std::vector<const char *> cached_argv;
+      if (d->argc > 0)
+       {
+         std::vector<const char *> cached_argv;
 
-      for (const auto &arg : argv)
-       cached_argv.push_back (macro_bcache_str (t, arg.c_str ()));
+         for (const auto &arg : argv)
+           cached_argv.push_back (macro_bcache_str (t, arg.c_str ()));
 
-      /* Now bcache the array of argument pointers itself.  */
-      d->argv = macro_bcache (t, cached_argv.data (),
-                             cached_argv.size () * sizeof (const char *));
+         /* Now bcache the array of argument pointers itself.  */
+         d->argv = macro_bcache (t, cached_argv.data (),
+                                 cached_argv.size () * sizeof (const char *));
+       }
     }
   else
     d->argc = special_kind;