This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/4] Fix latent bug in source cache


The source cache was not returning the final \n of the requested range
of lines.  This caused regressions with later patches in this series,
so this patch pre-emptively fixes the bug.

This adds a self-test of "extract_lines" to the source cache code.  To
make it simpler to test, I changed extract_lines to be a static
function, and changed it's API a bit.

gdb/ChangeLog
2019-07-26  Tom Tromey  <tromey@adacore.com>

	* source-cache.c (extract_lines): No longer a method.
	Changed type of parameter.  Include final newline.
	(selftests::extract_lines_test): New function.
	(_initialize_source_cache): Likewise.
	* source-cache.h (class source_cache)
	<extract_lines>: Don't declare.
---
 gdb/ChangeLog      |  9 +++++++++
 gdb/source-cache.c | 49 +++++++++++++++++++++++++++++++++++-----------
 gdb/source-cache.h |  6 ------
 3 files changed, 47 insertions(+), 17 deletions(-)

diff --git a/gdb/source-cache.c b/gdb/source-cache.c
index f5bb641a22b..f0cb6b80059 100644
--- a/gdb/source-cache.c
+++ b/gdb/source-cache.c
@@ -22,6 +22,7 @@
 #include "source.h"
 #include "cli/cli-style.h"
 #include "symtab.h"
+#include "gdbsupport/selftest.h"
 
 #ifdef HAVE_SOURCE_HIGHLIGHT
 /* If Gnulib redirects 'open' and 'close' to its replacements
@@ -80,11 +81,12 @@ source_cache::get_plain_source_lines (struct symtab *s, int first_line,
   return true;
 }
 
-/* See source-cache.h.  */
-
-std::string
-source_cache::extract_lines (const struct source_text &text, int first_line,
-			     int last_line)
+/* A helper function for get_plain_source_lines that extracts the
+   desired source lines from TEXT, putting them into LINES_OUT.  The
+   arguments are as for get_source_lines.  The return value is the
+   desired lines.  */
+static std::string
+extract_lines (const std::string &text, int first_line, int last_line)
 {
   int lineno = 1;
   std::string::size_type pos = 0;
@@ -92,7 +94,7 @@ source_cache::extract_lines (const struct source_text &text, int first_line,
 
   while (pos != std::string::npos && lineno <= last_line)
     {
-      std::string::size_type new_pos = text.contents.find ('\n', pos);
+      std::string::size_type new_pos = text.find ('\n', pos);
 
       if (lineno == first_line)
 	first_pos = pos;
@@ -103,8 +105,10 @@ source_cache::extract_lines (const struct source_text &text, int first_line,
 	  if (first_pos == std::string::npos)
 	    return {};
 	  if (pos == std::string::npos)
-	    pos = text.contents.size ();
-	  return text.contents.substr (first_pos, pos - first_pos);
+	    pos = text.size ();
+	  else
+	    ++pos;
+	  return text.substr (first_pos, pos - first_pos);
 	}
       ++lineno;
       ++pos;
@@ -187,7 +191,7 @@ source_cache::get_source_lines (struct symtab *s, int first_line,
 	{
 	  if (item.fullname == fullname)
 	    {
-	      *lines = extract_lines (item, first_line, last_line);
+	      *lines = extract_lines (item.contents, first_line, last_line);
 	      return true;
 	    }
 	}
@@ -233,8 +237,8 @@ source_cache::get_source_lines (struct symtab *s, int first_line,
 	      if (m_source_map.size () > MAX_ENTRIES)
 		m_source_map.erase (m_source_map.begin ());
 
-	      *lines = extract_lines (m_source_map.back (), first_line,
-				      last_line);
+	      *lines = extract_lines (m_source_map.back ().contents,
+				      first_line, last_line);
 	      return true;
 	    }
 	}
@@ -243,3 +247,26 @@ source_cache::get_source_lines (struct symtab *s, int first_line,
 
   return get_plain_source_lines (s, first_line, last_line, lines);
 }
+
+#if GDB_SELF_TEST
+namespace selftests
+{
+static void extract_lines_test ()
+{
+  std::string input_text = "abc\ndef\nghi\njkl\n";
+
+  SELF_CHECK (extract_lines (input_text, 1, 1) == "abc\n");
+  SELF_CHECK (extract_lines (input_text, 2, 1) == "");
+  SELF_CHECK (extract_lines (input_text, 1, 2) == "abc\ndef\n");
+  SELF_CHECK (extract_lines ("abc", 1, 1) == "abc");
+}
+}
+#endif
+
+void
+_initialize_source_cache ()
+{
+#if GDB_SELF_TEST
+  selftests::register_test ("source-cache", selftests::extract_lines_test);
+#endif
+}
diff --git a/gdb/source-cache.h b/gdb/source-cache.h
index e2e25a170fd..a00efbf3fba 100644
--- a/gdb/source-cache.h
+++ b/gdb/source-cache.h
@@ -63,12 +63,6 @@ private:
      are as for get_source_lines.  */
   bool get_plain_source_lines (struct symtab *s, int first_line,
 			       int last_line, std::string *lines_out);
-  /* A helper function for get_plain_source_lines that extracts the
-     desired source lines from TEXT, putting them into LINES_OUT.  The
-     arguments are as for get_source_lines.  The return value is the
-     desired lines.  */
-  std::string extract_lines (const struct source_text &text, int first_line,
-			     int last_line);
 
   /* The contents of the cache.  */
   std::vector<source_text> m_source_map;
-- 
2.20.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]