summaryrefslogtreecommitdiff
path: root/gdbserver_tests/README_DEVELOPERS
blob: 1509a8371181ed58029a12cd87ddc2890f4fc3b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
Automatic regression tests:
---------------------------
The Valgrind gdbserver automatic tests are by default
executed as part of the Valgrind test suite:
   make regtest

By default, these tests are running with the gdb found at
Valgrind configure time.

If you want to test with another gdb version, you can do:
  make regtest GDB=/path/to/another/gdb

or (to just run the gdbserver tests with another gdb):
  cd gdbserver_tests
  make check
  cd ..
  gdbserver_tests/make_local_links /path/to/another/gdb
  perl tests/vg_regtest gdbserver_tests

The minimum version to use the Valgrind gdbserver is gdb >= 6.5.
    Previous versions do not have the 'target remote |' command.  It
    would be possible to use an older version by having a tcp relay
    application between gdb and vgdb (or, alternatively, change vgdb
    so that it could read/write from/to a tcpip socket rather than
    read/write from stdin/stdout.

The tests have been run on various platforms using gdb 7.2
and on some platforms gdb 7.0 and 7.1.
Some gdb tests implies a gdb >= 7.2. (these are automatically disabled
if testing with a lower version).
Test behaviour with gdb < 7.0 is unknown: some might fail,
some might block or loop for a very long time.

Some tests implies to have a vgdb "ptrace invoker" capable.

The prerequisite are established during make regtest (using marker files).
Each test verifies the prerequisite using the prereq: line.

In case of failing tests
------------------------
When executed with a new gdb version and/or depending on the OS version,
gdbserver tests might often fail due to (irrelevant) differences.
Such irrelevant differences have to be filtered by gdbserver_tests/filter_gdb.

You are welcome to fix such bugs by enhancing filter_gdb.

Alternatively, to report such problems, the best is to re-run
the gdbserver tests the following way:
   perl tests/vg_regtest --keep-unfiltered gdbserver_tests

Then file a bug in bugzilla, giving the following information:
  output of
    gdbserver_tests/gdb --version
    uname -a
    cat /etc/issue
    valgrind --version (and/or svn version)
  and attach a tar file containing all the *.out and *.diff
  files in gdbserver_tests directory

If a gdbserver test fails for other reasons, you can run the test
manually in two windows:
  In one window, the valgrind
  In another window, you launch gdb yourself, and you copy paste
  the command from xxxx.stdinB.gdb. This might help to see what is
  wrong.

Another good trick is also to execute the same kind of actions
using a gdb connected to the gdbserver part of gdb.
You can examine what is happening by enabling the trace
of the packets being sent using the gdb command:
   set debug remote 1
Note however that the packets might be different
(e.g. the Valgrind gdbserver understands the 'P' packet,
which might not be understood by the gdbserver of gdb).

Naming conventions:
-------------------

The gdbserver tests are done with various Valgrind tools.  A gdbserver
test using a tool xxxxxx should have its name starting with the 'short
two letters code' of this tool.  For example, the test mcvabits.vgtest
is using Memcheck tool, while the test mssnapshot.vgtest is using
massif tool.

Typically, a gdbserver test implies to launch two programs:
     prog: a program running under valgrind
     progB: another program (typically, either gdb or vgdb standalone)
The conventions about how to specify the 2nd program in a .vgtest
are explained in the file ../tests/vg_regtest.in
Many tests are using gdb as progB. The input for gdb is named
xxxxxx.stdinB.gdb.

One day, we might imagine to run tests in parallel.
So, each test gets its own '--vgdb-prefix' argument.
This also help to avoid interactions between two successive tests:
if a previous test stayed blocked, the vgdb of the next test
will not report an error due to multiple possible FIFOs.


Rational for test approach
--------------------------
Two approaches have been looked at:
  V: use the 'vg_regtest' approach used by the rest of Valgrind tests
  G: use the gdb Dejagnu test framework.

Advantages of V: much simpler that G, known by Valgrind developpers,
no additional dependency for the Valgrind build and test.

Disadvantages of V: not well suited to testing of interactive tools,
very unflexible way to test the results (everything is in "template"
files), templates contains often irrelevant data for the test but it
can make the test fail.  After writing 13 tests, it looks like the
template diff approach is quite fragile (e.g. changing the gdb version
and/or the OS version influences the output of irrelevant things which
are part of the template).

A more flexible template filtering is needed.
Maybe something like:
The program under test is outputting its instructions to be filtered in
special markers e.g.
#pushf filter_addresses | filter_messages
... some output
#pushf an_additional_filter
... some other output, filtered by both the first and second push
#popf
... here output filtered only by the first pushf
#popf

Advantages of G: much more powerful, well suited to test a gdb with a
gdbserver, tests can verify specifically some output without being
impacted by other output, allow to test Valgrind gdbserver with the
all of the gdb test suite (but a lot of tests will rather test gdb
than Valgrind gdbserver).

Disadvantages: not an easy beast to understand and master, running the
whole gdb testsuite with Valgrind gdbserver looks to be a challenge.

Currently, tests are written with vg_regtest. Approach G will be looked at it
again (e.g. to complement V) once a basic set of tests are available. 


Manual tests still to automate:
-------------------------------

Validate  monitor commands abbreviation recognition
***************************************************
mo v.info all_errors            # to show all errors recorded so far
mo v.i a                        # the same
mo v                            # must give an error: v can match v.set v.info
mo v                            # the same            v
mo v.                           # the same            v.

test of gdb detaching or dying
******************************
valgrind --vgdb=yes --vgdb-error=0 --vgdb-poll=500 ./t

in another window

gdb ./t
set remotetimeout 100
target remote|vgdb
detach                         valgrind continues
target remote|vgdb             reattach
detach                         valgrind continues
target remote|vgdb             reattach
monitor v.wait                 no effect



test of valgrind/gdb output redirection
***************************************
valgrind --vgdb=yes --vgdb-error=1 --vgdb-poll=500 ./t

in another window

**** command to type***         ****** expected behaviour
gdb ./t
set remotetimeout 1000 
target remote | vgdb
mo v.set vgdb-error 1000        # so that valgrind does stop only at error 1000 and after
mo v.set gdb_output             # to have further valgrind errors output in gdb
c                               # continue, some errors will appear
C-c                             # interrupt program
mo v.set log_output             # to set back the valgrind output to normal process log output
mo l                            # leak output to appear in log of process
mo v.set mixed_output
mo l                            # leak output to appear in gdb



test with a big executable: firefox
***********************************
valgrind --vgdb=yes --vgdb-error=1000 --vgdb-poll=50000 --trace-children=yes firefox 2>&1 | tee f.out

wait for some messages from the "big" firefox executable to appear.
Then:

gdb /usr/lib/firefox-3.5/firefox
target remote | vgdb
... then you can do various next/print/bt/bt full/break/... to see it is working

bulk test with the above
************************
to verify there is no race condition/no reentrance problem 
between gdbserver code and valgrind:
start firefox like in the previous test.
In another window, do:
  while true
  do
    vgdb leak
    sleep 1
  done

NB: this will make firefox run extremely slow, as it will do a leak
search every second.

 
Test of "jump" functionality
----------------------------
... to be done : put two breaks, jump over one.
... same but when error is encountered


* test with --max-invoke-ms=0
-----------------------------
valgrind --vgdb=yes ./t
... wait till you see "petachounok sleeping 4 of 15
then try to gdb it

!!!! this often causes gdb to report a protocol timeout.
use gdb set remotetimeout <a big time> to avoid that.
The symptoms of a timeout are:
    (gdb) tar rem|vgdb --max-invoke-ms=0
    Remote debugging using |vgdb --max-invoke-ms=0
    relaying data between gdb and process 2930
    Ignoring packet error, continuing...
    warning: unrecognized item "timeout" in "qSupported" response

* tests of shadow registers
----------------------------
Show/modify shadow registers