[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gdb-patches
Subject:    Re: [PATCH 6/6] Add simple_search_memory unit tests
From:       Simon Marchi <simark () simark ! ca>
Date:       2020-07-30 13:12:02
Message-ID: f5d9ae87-5b40-9fd7-368b-83d97a4d05ec () simark ! ca
[Download RAW message or body]

On 2020-07-23 4:12 p.m., Tom Tromey wrote:
> This adds some unit tests for simple_search_memory.  I tried here to
> reproduce some bugs (PR gdb/11158 and PR gdb/17756), but was unable
> to.
> 
> 2020-07-23  Tom Tromey  <tromey@adacore.com>
> 
> 	* unittests/search-memory-selftests.c: New file.
> 	* Makefile.in (SELFTESTS_SRCS): Add
> 	unittests/search-memory-selftests.c.
> ---
> gdb/ChangeLog                           |   6 ++
> gdb/Makefile.in                         |   1 +
> gdb/unittests/search-memory-selftests.c | 102 ++++++++++++++++++++++++
> 3 files changed, 109 insertions(+)
> create mode 100644 gdb/unittests/search-memory-selftests.c
> 
> diff --git a/gdb/Makefile.in b/gdb/Makefile.in
> index 8feb5e39ff5..e279b8d944a 100644
> --- a/gdb/Makefile.in
> +++ b/gdb/Makefile.in
> @@ -450,6 +450,7 @@ SELFTESTS_SRCS = \
> 	unittests/scoped_fd-selftests.c \
> 	unittests/scoped_mmap-selftests.c \
> 	unittests/scoped_restore-selftests.c \
> +	unittests/search-memory-selftests.c \
> 	unittests/string_view-selftests.c \
> 	unittests/style-selftests.c \
> 	unittests/tracepoint-selftests.c \
> diff --git a/gdb/unittests/search-memory-selftests.c \
> b/gdb/unittests/search-memory-selftests.c new file mode 100644
> index 00000000000..4bf93756ed6
> --- /dev/null
> +++ b/gdb/unittests/search-memory-selftests.c
> @@ -0,0 +1,102 @@
> +/* Self tests for simple_search_memory for GDB, the GNU debugger.
> +
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +
> +   This file is part of GDB.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#include "gdbsupport/common-defs.h"
> +#include "gdbsupport/selftest.h"
> +#include "target/target.h"
> +
> +namespace selftests {
> +namespace search_memory_tests {
> +
> +/* Note: Also defined in target/search.c.  */
> +#define SEARCH_CHUNK_SIZE 16000

I wonder if this should be defined in target/target.h instead.

> +
> +static void
> +run_tests ()
> +{
> +  size_t size = 2 * SEARCH_CHUNK_SIZE + 1;
> +
> +  std::vector<gdb_byte> data (size);
> +  data[size - 1] = 'x';
> +
> +  bool read_fully = false;
> +  bool read_off_end = false;
> +  auto read_memory = [&] (CORE_ADDR from, gdb_byte *out, size_t len)
> +    {
> +      if (from + len > data.size ())
> +	read_off_end = true;
> +      else
> +	memcpy (out, &data[from], len);
> +      if (from + len == data.size ())
> +	read_fully = true;
> +      return true;
> +    };
> +
> +  gdb_byte pattern = 'x';
> +
> +  CORE_ADDR addr = 0;
> +  int result = simple_search_memory (read_memory, 0, data.size (),
> +				     &pattern, 1, &addr);
> +  /* In this case we don't care if read_fully was set or not.  */
> +  SELF_CHECK (result == 1);
> +  SELF_CHECK (!read_off_end);
> +  SELF_CHECK (addr == size - 1);
> +
> +  addr = 0;
> +  read_fully = false;
> +  read_off_end = false;
> +  pattern = 'q';
> +  result = simple_search_memory (read_memory, 0, data.size (),
> +				 &pattern, 1, &addr);
> +  SELF_CHECK (result == 0);
> +  SELF_CHECK (!read_off_end);
> +  SELF_CHECK (read_fully);
> +  SELF_CHECK (addr == 0);
> +
> +  /* Setup from PR gdb/17756.  */
> +  size = 0x7bb00;
> +  data = std::vector<gdb_byte> (size);
> +  const CORE_ADDR base_addr = 0x08370000;
> +  const gdb_byte wpattern[] = { 0x90, 0x8b, 0x98, 0x8 };
> +  const CORE_ADDR found_addr = 0x837bac8;
> +  memcpy (&data[found_addr - base_addr], wpattern, sizeof (wpattern));
> +
> +  auto read_memory_2 = [&] (CORE_ADDR from, gdb_byte *out, size_t len)
> +    {
> +      memcpy (out, &data[from - base_addr], len);
> +      return true;
> +    };
> +
> +  result = simple_search_memory (read_memory_2, base_addr, data.size (),
> +				 wpattern, sizeof (wpattern), &addr);
> +  SELF_CHECK (result == 1);
> +  SELF_CHECK (addr == found_addr);
> +}

I compile with -D_GLIBCXX_DEBUG=1, and it aborts when running this test:

Running selftest search_memory.
/usr/include/c++/10.1.0/debug/vector:427:
In function:
    std::__debug::vector<_Tp, _Allocator>::reference
    std::__debug::vector<_Tp,
    _Allocator>::operator[](std::__debug::vector<_Tp,
    _Allocator>::size_type) [with _Tp = unsigned char; _Allocator =
    gdb::default_init_allocator<unsigned char, std::allocator<unsigned char>
    >; std::__debug::vector<_Tp, _Allocator>::reference = unsigned char&;
    std::__debug::vector<_Tp, _Allocator>::size_type = long unsigned int]

Error: attempt to subscript container with out-of-bounds index 16000, but
container only holds 16000 elements.

Objects involved in the operation:
    sequence "this" @ 0x0x7ffc6e54f870 {
      type = std::__debug::vector<unsigned char, gdb::default_init_allocator<unsigned \
char, std::allocator<unsigned char> > >;  }

Simon


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic