forked from Imagelibrary/rtems
322 lines
6.3 KiB
C
322 lines
6.3 KiB
C
/*
|
|
* Debugger test remote.
|
|
*
|
|
* Copyright (c) 2016 Chris Johns (chrisj@rtems.org)
|
|
*
|
|
* The license and distribution terms for this file may be
|
|
* found in the file LICENSE in this distribution or at
|
|
* http://www.rtems.org/license/LICENSE.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include "tmacros.h"
|
|
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
#include <rtems/rtems-debugger.h>
|
|
#include <rtems/debugger/rtems-debugger-server.h>
|
|
#include <rtems/debugger/rtems-debugger-remote.h>
|
|
|
|
#include "system.h"
|
|
|
|
/**
|
|
* Remote data.
|
|
*/
|
|
typedef struct
|
|
{
|
|
int connect_count;
|
|
bool connected;
|
|
size_t out;
|
|
size_t in;
|
|
} rtems_debugger_remote_test;
|
|
|
|
static const char* out[] =
|
|
{
|
|
"+",
|
|
"xxxxx",
|
|
"$x#aa",
|
|
|
|
"$qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;"
|
|
"vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+#df",
|
|
|
|
"$vMustReplyEmpty#3a",
|
|
"+",
|
|
|
|
"$Hgp0.0#ad",
|
|
"+",
|
|
|
|
"$qTStatus#49",
|
|
"+",
|
|
|
|
"$?#3f",
|
|
"+",
|
|
|
|
"$qfThreadInfo#bb",
|
|
"+",
|
|
|
|
"$qsThreadInfo#c8",
|
|
"-",
|
|
"+",
|
|
|
|
"$qAttached:1#fa",
|
|
"+",
|
|
|
|
"$Hc-1#09",
|
|
"+",
|
|
|
|
"$qOffsets#4b",
|
|
"+",
|
|
|
|
"$g#67"
|
|
"+",
|
|
|
|
"$D;1#b0",
|
|
"+"
|
|
};
|
|
|
|
static const char* in[] =
|
|
{
|
|
/* 0 */
|
|
"-",
|
|
|
|
/* 1 */
|
|
"+",
|
|
"$qSupported:PacketSize=4096;QNonStop-;multiprocess+;swbreak+;hwbreak-;"
|
|
"qRelocInsn-;fork-events-;vfork-events-;exec-events-;vContSupported+;"
|
|
"QThreadEvents-;no-resumed+#b3",
|
|
|
|
/* 3 */
|
|
"+",
|
|
"$#00",
|
|
|
|
/* 5 */
|
|
"+",
|
|
"$OK#9a",
|
|
|
|
/* 7 */
|
|
"+",
|
|
"$#00",
|
|
|
|
/* 9 */
|
|
"+",
|
|
"$T00thread:p1.0a010001;#23",
|
|
|
|
/* 11 */
|
|
"+",
|
|
"**",
|
|
|
|
/* 13 */
|
|
"+",
|
|
"$l#6c",
|
|
"$l#6c",
|
|
|
|
/* 16 */
|
|
"+",
|
|
"$1#31",
|
|
|
|
/* 18 */
|
|
"+",
|
|
"$OK#9a",
|
|
|
|
/* 20 */
|
|
"+",
|
|
"$#00",
|
|
|
|
/* 22 */
|
|
"+",
|
|
"**",
|
|
|
|
"+",
|
|
"$OK#9a"
|
|
};
|
|
|
|
static int
|
|
test_remote_begin(rtems_debugger_remote* remote, const char* device)
|
|
{
|
|
rtems_debugger_remote_test* test;
|
|
|
|
rtems_debugger_printf("error: rtems-db: test remote: begin\n");
|
|
|
|
rtems_debugger_lock();
|
|
|
|
/*
|
|
* Check the device.
|
|
*/
|
|
rtems_test_assert(strcmp(device, "something") == 0);
|
|
|
|
test = malloc(sizeof(rtems_debugger_remote_test));
|
|
rtems_test_assert(test != NULL);
|
|
|
|
remote->data = test;
|
|
|
|
test->connect_count = 0;
|
|
test->connected = false;
|
|
test->out = 0;
|
|
test->in = 0;
|
|
|
|
rtems_debugger_unlock();
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
test_remote_end(rtems_debugger_remote* remote)
|
|
{
|
|
rtems_debugger_remote_test* test;
|
|
|
|
rtems_debugger_printf("error: rtems-db: test remote: end\n");
|
|
|
|
rtems_debugger_lock();
|
|
|
|
rtems_test_assert(remote != NULL);
|
|
rtems_test_assert(remote->data != NULL);
|
|
test = (rtems_debugger_remote_test*) remote->data;
|
|
|
|
test->connected = false;
|
|
|
|
free(test);
|
|
|
|
rtems_debugger_unlock();
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
test_remote_connect(rtems_debugger_remote* remote)
|
|
{
|
|
rtems_debugger_remote_test* test;
|
|
|
|
rtems_test_assert(remote != NULL);
|
|
rtems_test_assert(remote->data != NULL);
|
|
test = (rtems_debugger_remote_test*) remote->data;
|
|
|
|
if (test->connect_count > 0) {
|
|
rtems_event_set out = 0;
|
|
rtems_test_assert(rtems_event_receive(RTEMS_EVENT_1,
|
|
RTEMS_EVENT_ALL | RTEMS_WAIT,
|
|
RTEMS_NO_TIMEOUT,
|
|
&out) == RTEMS_SUCCESSFUL);
|
|
}
|
|
|
|
rtems_debugger_printf("error: rtems-db: test remote: connect\n");
|
|
|
|
++test->connect_count;
|
|
test->connected = true;
|
|
test->out = 0;
|
|
test->in = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
test_remote_disconnect(rtems_debugger_remote* remote)
|
|
{
|
|
rtems_debugger_remote_test* test;
|
|
|
|
rtems_test_assert(remote != NULL);
|
|
rtems_test_assert(remote->data != NULL);
|
|
test = (rtems_debugger_remote_test*) remote->data;
|
|
|
|
rtems_debugger_printf("rtems-db: test remote: disconnect host\n");
|
|
|
|
rtems_debugger_lock();
|
|
|
|
rtems_test_assert(test->connected == true);
|
|
|
|
test->connected = false;
|
|
|
|
rtems_debugger_unlock();
|
|
|
|
return 0;
|
|
}
|
|
|
|
static bool
|
|
test_remote_isconnected(rtems_debugger_remote* remote)
|
|
{
|
|
rtems_debugger_remote_test* test;
|
|
bool isconnected;
|
|
rtems_test_assert(remote != NULL);
|
|
rtems_test_assert(remote->data != NULL);
|
|
test = (rtems_debugger_remote_test*) remote->data;
|
|
isconnected = test != NULL && test->connected;
|
|
rtems_debugger_printf("rtems-db: test remote: isconnected: %s\n",
|
|
isconnected ? "connected" : "not-connected");
|
|
return isconnected;
|
|
}
|
|
|
|
static void
|
|
test_remote_print(const char* label, const char* buf, size_t size)
|
|
{
|
|
printf(" remote: %s: ", label);
|
|
while (size-- > 0) {
|
|
printf("%c", *buf++);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
static ssize_t
|
|
test_remote_receive(rtems_debugger_remote* remote,
|
|
void* buf,
|
|
size_t nbytes)
|
|
{
|
|
rtems_debugger_remote_test* test;
|
|
size_t len;
|
|
rtems_test_assert(remote != NULL);
|
|
rtems_test_assert(remote->data != NULL);
|
|
test = (rtems_debugger_remote_test*) remote->data;
|
|
rtems_test_assert(test->out < RTEMS_DEBUGGER_NUMOF(out));
|
|
len = strlen(out[test->out]);
|
|
printf(" remote: rx: message=%zu length=%zu\n", test->out, len);
|
|
test_remote_print("rx", out[test->out], len);
|
|
rtems_test_assert(len < nbytes);
|
|
memcpy(buf, out[test->out++], len);
|
|
return len;
|
|
}
|
|
|
|
static ssize_t
|
|
test_remote_send(rtems_debugger_remote* remote,
|
|
const void* buf,
|
|
size_t nbytes)
|
|
{
|
|
rtems_debugger_remote_test* test;
|
|
size_t len;
|
|
bool no_match;
|
|
rtems_test_assert(remote != NULL);
|
|
rtems_test_assert(remote->data != NULL);
|
|
test = (rtems_debugger_remote_test*) remote->data;
|
|
rtems_test_assert(test->in < RTEMS_DEBUGGER_NUMOF(in));
|
|
len = strlen(in[test->in]);
|
|
no_match = len == 2 && strcmp(in[test->in], "**") == 0;
|
|
printf(" remote: tx: message=%zu length=%zu\n", test->in, len);
|
|
if (!no_match)
|
|
rtems_test_assert(len == nbytes);
|
|
test_remote_print("tx", buf, nbytes);
|
|
if (!no_match)
|
|
rtems_test_assert(memcmp(buf, in[test->in], nbytes) == 0);
|
|
test->in++;
|
|
return nbytes;
|
|
}
|
|
|
|
static rtems_debugger_remote remote_test =
|
|
{
|
|
.name = "test",
|
|
.begin = test_remote_begin,
|
|
.end = test_remote_end,
|
|
.connect = test_remote_connect,
|
|
.disconnect = test_remote_disconnect,
|
|
.isconnected = test_remote_isconnected,
|
|
.read = test_remote_receive,
|
|
.write = test_remote_send
|
|
};
|
|
|
|
int
|
|
rtems_debugger_register_test_remote(void)
|
|
{
|
|
return rtems_debugger_remote_register(&remote_test);
|
|
}
|