Add unit test to gdbarch methods register_to_value and value_to_register
authorYao Qi <yao.qi@linaro.org>
Wed, 24 May 2017 21:15:23 +0000 (22:15 +0100)
committerYao Qi <yao.qi@linaro.org>
Wed, 24 May 2017 21:15:23 +0000 (22:15 +0100)
commitb77b02a5ca5a021ee8b5e5453e8843447d1132b2
tree8d2aaba59e243f11fd8384b07a24975e37414c81
parente521e87e8514b9d3497208b70bcd067f132c58ed
Add unit test to gdbarch methods register_to_value and value_to_register

This patch adds one unit test for gdbarch methods register_to_value and
value_to_register.  The test pass different combinations of {regnu, type}
to gdbarch_register_to_value and gdbarch_value_to_register.  In order
to do the test, add a new function create_new_frame to create a fake
frame.  It can be improved after we converted frame_info to class.

In order to isolate regcache (from target_ops operations on writing
registers, like target_store_registers), the sub-class of regcache in the
test override raw_write.  Also, in order to get the right regcache from
get_thread_arch_aspace_regcache, the sub-class of regcache inserts itself
to current_regcache.

Suppose I incorrectly modified the size of buffer as below,

@@ -1228,7 +1228,7 @@ ia64_register_to_value (struct frame_info *frame, int regnum,
                        int *optimizedp, int *unavailablep)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte in[MAX_REGISTER_SIZE];
+  gdb_byte in[1];

   /* Convert to TYPE.  */
   if (!get_frame_register_bytes (frame, regnum, 0,

build GDB with "-fsanitize=address" and run unittest.exp, asan can detect
such error

==2302==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff98193870 at pc 0xbd55ea bp 0x7fff981935a0 sp 0x7fff98193598
WRITE of size 16 at 0x7fff98193870 thread T0
    #0 0xbd55e9 in frame_register_unwind(frame_info*, int, int*, int*, lval_type*, unsigned long*, int*, unsigned char*) /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:1119
    #1 0xbd58c8 in frame_register(frame_info*, int, int*, int*, lval_type*, unsigned long*, int*, unsigned char*) /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:1147
    #2 0xbd6e25 in get_frame_register_bytes(frame_info*, int, unsigned long, int, unsigned char*, int*, int*) /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:1427
    #3 0x70080a in ia64_register_to_value /home/yao/SourceCode/gnu/gdb/git/gdb/ia64-tdep.c:1236
    #4 0xbf570e in gdbarch_register_to_value(gdbarch*, frame_info*, int, type*, unsigned char*, int*, int*) /home/yao/SourceCode/gnu/gdb/git/gdb/gdbarch.c:2619
    #5 0xc05975 in register_to_value_test /home/yao/SourceCode/gnu/gdb/git/gdb/gdbarch-selftests.c:131

Or, even if GDB is not built with asan, GDB just crashes.

*** stack smashing detected ***: ./gdb terminated
Aborted (core dumped)

gdb:

2017-05-24  Yao Qi  <yao.qi@linaro.org>

* Makefile.in (SFILES): Add gdbarch-selftests.c.
(COMMON_OBS): Add gdbarch-selftests.o.
* frame.c [GDB_SELF_TESTS] (create_new_frame): New function.
* frame.h [GDB_SELF_TESTS] (create_new_frame): Declare.
* gdbarch-selftests.c: New file.
* regcache.h (regcache) <~regcache>: Mark it virtual if
GDB_SELF_TEST.
<raw_write>: Likewise.
gdb/ChangeLog
gdb/Makefile.in
gdb/frame.c
gdb/frame.h
gdb/gdbarch-selftests.c [new file with mode: 0644]
gdb/regcache.h