gdb/debuginfod: Prevent out_of_range exception
authorAaron Merey <amerey@redhat.com>
Fri, 8 Apr 2022 22:50:56 +0000 (18:50 -0400)
committerAaron Merey <amerey@redhat.com>
Wed, 20 Apr 2022 21:40:05 +0000 (17:40 -0400)
Trailing whitespace in the string of debuginfod URLs causes an
out_of_range exception during the printing of URLs for the first
use notice.

To fix this, stop printing URLs when the substring to be printed
consists only of whitespace.

Also add first use notice testcases.

Co-Authored-By: Pedro Alves <pedro@palves.net>
gdb/debuginfod-support.c
gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp

index 6c2d3fb29519feb720a5c54823a7d2a2cca2764d..4ce2e786b6a1b75890b16f5155658ab8ee66e894 100644 (file)
@@ -187,10 +187,11 @@ debuginfod_is_enabled ()
       gdb::string_view url_view (urls);
       while (true)
        {
-         url_view = url_view.substr (url_view.find_first_not_of (' '));
-         if (url_view.empty ())
+         size_t off = url_view.find_first_not_of (' ');
+         if (off == gdb::string_view::npos)
            break;
-         size_t off = url_view.find_first_of (' ');
+         url_view = url_view.substr (off);
+         off = url_view.find_first_of (' ');
          gdb_printf
            (_("  <%ps>\n"),
             styled_string (file_name_style.style (),
index f12ed7d486ca5f3a8318d757ed755a4fe63be0a4..6da9a86faa8e38e158f37c28b39679fa66f2f2ed 100644 (file)
@@ -186,6 +186,28 @@ proc no_url { } {
     gdb_test "core $::corefile" ".*in ?? ().*" "file [file tail $::corefile]"
 }
 
+# Test that GDB prints the debuginfod URLs when loading files.  URLS
+# is the string set in the DEBUGINFOD_URLS environment variable.
+# PATTERN_RE is the URLs pattern we expect to see out of GDB.  TEST is
+# the test name.
+
+proc test_urls {urls pattern_re test} {
+    setenv DEBUGINFOD_URLS $urls
+    clean_restart
+
+    if {$pattern_re != ""} {
+       set urls_re " +${pattern_re}\r\n"
+    } else {
+       set urls_re ""
+    }
+
+    # Use "with confirm off" to avoid having to deal with the
+    # "Enable debuginfod for this session? (y or [n])" question.
+    gdb_test "with confirm off -- file $::binfile" \
+       "following URLs:\r\n${urls_re}Debuginfod .*" \
+       $test
+}
+
 proc local_url { } {
     global binfile outputdir db debugdir
 
@@ -279,6 +301,46 @@ proc local_url { } {
     gdb_test_no_output "set debuginfod enabled on"
     gdb_test "file $binfile" ".*Reading symbols from.*debuginfo.*" \
        "file [file tail $binfile] cmd on"
+
+    # Test that URLs are printed correctly for the first-use notice.
+
+    # Empty URLS disables Debuginfod.
+    setenv DEBUGINFOD_URLS ""
+    clean_restart
+    # Disable confirmation to avoid having to deal with a query.  See
+    # test_urls.
+    gdb_test_multiple "with confirm off -- file $binfile" "notice empty URL" {
+       -re ".*Enable debuginfod.*" {
+           fail $gdb_test_name
+       }
+       -re -wrap "" {
+           pass $gdb_test_name
+       }
+    }
+
+    test_urls "   " \
+        "" \
+        "notice whitespace URL"
+
+    set url "http://127.0.0.1:$port"
+
+    test_urls $url \
+       "<$url>" \
+       "notice 1 URL"
+
+    test_urls "  $url  " \
+       "<$url>" \
+       "notice 1 URL with whitespace"
+
+    set url2 "127.0.0.1:$port"
+
+    test_urls "$url $url2" \
+       "<$url>\r\n +<$url2>" \
+       "notice 2 URLs"
+
+    test_urls "  $url $url2  " \
+       "<$url>\r\n +<$url2>" \
+       "notice 2 URLs with whitespace"
 }
 
 set envlist \