summaryrefslogtreecommitdiff
path: root/gdb/regcache.h
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2017-10-04 18:21:09 +0100
committerPedro Alves <palves@redhat.com>2017-10-04 18:21:09 +0100
commit55b11ddf16b97b9c50ed480bc9da8b3e1c6c4198 (patch)
tree96cca06271e32481a56da32e396010863009d012 /gdb/regcache.h
parent4c71c1059f876fcca9809f7b6372b721ddb83635 (diff)
downloadbinutils-gdb-55b11ddf16b97b9c50ed480bc9da8b3e1c6c4198.tar.gz
Redesign mock environment for gdbarch selftests
A following patch will remove this hack from within regcache's implementation: struct regcache * get_thread_arch_regcache (ptid_t ptid, struct gdbarch *gdbarch) { struct address_space *aspace; /* For the benefit of "maint print registers" & co when debugging an executable, allow dumping the regcache even when there is no thread selected (target_thread_address_space internal-errors if no address space is found). Note that normal user commands will fail higher up on the call stack due to no target_has_registers. */ aspace = (ptid_equal (null_ptid, ptid) ? NULL : target_thread_address_space (ptid)); i.e., it'll no longer be possible to try to build a regcache for null_ptid. That change alone would regress the gdbarch self tests though, causing this: (gdb) maintenance selftest [...] Running selftest register_to_value. src/gdb/inferior.c:309: internal-error: inferior* find_inferior_pid(int): Assertion `pid != 0' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) FAIL: gdb.gdb/unittest.exp: maintenance selftest (GDB internal error) The problem is that the way the mocking environment for those unit tests is written is a bit fragile: it creates a special purpose regcache (and sentinel's frame), using whatever is the current inferior_ptid (usually null_ptid), and assumes get_current_regcache will find that in the regcache::current_regcache list. This commit changes the way the mock environment is created. It eliminates the special regcache and frame and instead creates a fuller mock environment, with a custom mock target_ops, and then a mock inferior and thread "running" on that target. If there's already a running target when you type "maint selftest", then we error out, instead of pushing a new target on top of the existing one (and thus killing the debug session). This results in: (gdb) maint selftest (...) Self test failed: arch i386: target already pushed Self test failed: arch i386:x86-64: target already pushed Self test failed: arch i386:x64-32: target already pushed Self test failed: arch i8086: target already pushed Self test failed: arch i386:intel: target already pushed Self test failed: arch i386:x86-64:intel: target already pushed Self test failed: arch i386:x64-32:intel: target already pushed Self test failed: arch i386:nacl: target already pushed Self test failed: arch i386:x86-64:nacl: target already pushed Self test failed: arch i386:x64-32:nacl: target already pushed Self test failed: self-test failed at /home/pedro/gdb/mygit/src/gdb/selftest-arch.c:86 (...) Ran 19 unit tests, 1 failed I think that's OK, because self tests are really meant to be run from a clean state right after GDB is started. I'm adding that erroring out just as safe measure just in case someone types "maint selftest" on the command line while already debugging something (as I've done it). (In my multi-target branch, where this patch originated from, we don't actually need to error out, because there each inferior has its own target stack). Also, note that the current code was doing: current_inferior()->gdbarch = gdbarch; without taking care to restore the previous gdbarch. This means that GDB's state was being left inconsistent after running the self tests, further supporting the point that there's probably not much expectation that mixing "maint selftests" and regular debugging in the same GDB invocation really works. This patch fixes that, regardless. gdb/ChangeLog: 2017-10-04 Pedro Alves <palves@redhat.com> * frame.c (create_test_frame): Delete. * frame.h (create_test_frame): Delete. * gdbarch-selftests.c: Include gdbthread.h and target.h. (class regcache_test): Delete. (test_target_has_registers, test_target_has_stack) (test_target_has_memory, test_target_prepare_to_store) (test_target_store_registers): New functions. (test_target_ops): New class. (register_to_value_test): Error out if there's already a process_stratum (or higher) target pushed. Create a fuller mock environment, with mock target_ops, inferior, address space, thread and inferior_ptid. * progspace.c (struct address_space): Move to ... * progspace.h (struct address_space): ... here. * regcache.h (regcache::~regcache, regcache::raw_write) [GDB_SELF_TEST]: No longer virtual.
Diffstat (limited to 'gdb/regcache.h')
-rw-r--r--gdb/regcache.h10
1 files changed, 0 insertions, 10 deletions
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 3ecdb3b1a32..6f42fb93769 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -252,11 +252,6 @@ public:
DISABLE_COPY_AND_ASSIGN (regcache);
- /* class regcache is only extended in unit test, so only mark it
- virtual when selftest is enabled. */
-#if GDB_SELF_TEST
- virtual
-#endif
~regcache ()
{
xfree (m_registers);
@@ -277,11 +272,6 @@ public:
enum register_status raw_read (int regnum, gdb_byte *buf);
- /* class regcache is only extended in unit test, so only mark it
- virtual when selftest is enabled. */
-#if GDB_SELF_TEST
- virtual
-#endif
void raw_write (int regnum, const gdb_byte *buf);
template<typename T, typename = RequireLongest<T>>