📄 thread-packets.c
字号:
static char * unpack_string(
char * src,
char * dest,
int length)
{
while (length--) *dest++ = *src++ ;
*dest = '\0' ;
return src ;
} /* unpack_string */
void output_threadid(char * title,threadref * ref)
{
char hexid[20] ;
pack_threadid(&hexid[0],ref) ; /* Convert threead id into hex */
hexid[16] = 0 ;
output_string(title) ;
output_string(&hexid[0]) ;
output_string("\n") ;
}
/* ------ REMOTE_UPK_THREAD_INFO_RESPONSE ------------------------------- */
/* Unpack the response of a detailed thread info packet */
/* Encoding: i'Q':8,i'R':8,argmask:16,threadid:64,(tag:8,length:16,data:x)* */
#define TAG_THREADID 1
#define TAG_EXISTS 2
#define TAG_DISPLAY 4
#define TAG_THREADNAME 8
#define TAG_MOREDISPLAY 16
int remote_upk_thread_info_response(
char * pkt,
threadref * expectedref ,
struct gdb_ext_thread_info * info)
{
int mask, length ;
unsigned int tag ;
threadref ref ;
char * limit = pkt + 500 ; /* plausable parsing limit */
int retval = 1 ;
PKT_TRACE("upk-threadinfo ",pkt) ;
/* info->threadid = 0 ; FIXME: implement zero_threadref */
info->active = 0 ;
info->display[0] = '\0' ;
info->shortname[0] = '\0' ;
info->more_display[0] = '\0' ;
/* Assume the characters indicating the packet type have been stripped */
pkt = unpack_int(pkt,&mask) ; /* arg mask */
pkt = unpack_threadid(pkt , &ref) ;
if (! threadmatch(&ref,expectedref))
{ /* This is an answer to a different request */
output_string("FAIL Thread mismatch\n") ;
output_threadid("ref ",&ref) ;
output_threadid("expected ",expectedref) ;
return 0 ;
}
copy_threadref(&info->threadid,&ref) ;
/* Loop on tagged fields , try to bail if somthing goes wrong */
if (mask==0) output_string("OOPS NO MASK \n") ;
while ((pkt < limit) && mask && *pkt) /* packets are terminated with nulls */
{
pkt = unpack_int(pkt,&tag) ; /* tag */
pkt = unpack_byte(pkt,&length) ; /* length */
if (! (tag & mask)) /* tags out of synch with mask */
{
output_string("FAIL: threadinfo tag mismatch\n") ;
retval = 0 ;
break ;
}
if (tag == TAG_THREADID)
{
output_string("unpack THREADID\n") ;
if (length != 16)
{
output_string("FAIL: length of threadid is not 16\n") ;
retval = 0 ;
break ;
}
pkt = unpack_threadid(pkt,&ref) ;
mask = mask & ~ TAG_THREADID ;
continue ;
}
if (tag == TAG_EXISTS)
{
info->active = stub_unpack_int(pkt,length) ;
pkt += length ;
mask = mask & ~(TAG_EXISTS) ;
if (length > 8)
{
output_string("FAIL: 'exists' length too long\n") ;
retval = 0 ;
break ;
}
continue ;
}
if (tag == TAG_THREADNAME)
{
pkt = unpack_string(pkt,&info->shortname[0],length) ;
mask = mask & ~TAG_THREADNAME ;
continue ;
}
if (tag == TAG_DISPLAY)
{
pkt = unpack_string(pkt,&info->display[0],length) ;
mask = mask & ~TAG_DISPLAY ;
continue ;
}
if (tag == TAG_MOREDISPLAY)
{
pkt = unpack_string(pkt,&info->more_display[0],length) ;
mask = mask & ~TAG_MOREDISPLAY ;
continue ;
}
output_string("FAIL: unknown info tag\n") ;
break ; /* Not a tag we know about */
}
return retval ;
} /* parse-thread_info_response */
/* ---- REMOTE_PACK_CURRTHREAD_REQUEST ---------------------------- */
/* This is a request to emit the T packet */
/* FORMAT: 'q':8,'C' */
char * remote_pack_currthread_request(char * pkt )
{
*pkt++ = 'q' ;
*pkt++ = 'C' ;
*pkt = '\0' ;
return pkt ;
} /* remote_pack_currthread_request */
/* ------- REMOTE_UPK_CURTHREAD_RESPONSE ----------------------- */
/* Unpack the interesting part of a T packet */
int remote_upk_currthread_response(
char * pkt,
int *thr ) /* Parse a T packet */
{
int retval = 0 ;
PKT_TRACE("upk-currthreadresp ",pkt) ;
#if 0
{
static char threadtag[8] = "thread" ;
int retval = 0 ;
int i , found ;
char ch ;
int quickid ;
/* Unpack as a t packet */
while (((ch = *pkt++) != ':') /* scan for : thread */
&& (ch != '\0')) /* stop at end of packet */
{
found = 0 ;
i = 0 ;
while ((ch = *pkt++) == threadtag[i++]) ;
if (i == 8) /* string match "thread" */
{
pkt = unpack_varlen_hex(pkt,&quickid) ;
retval = 1;
break ;
}
retval = 0 ;
}
}
#else
pkt = unpack_threadid(pkt, thr) ;
retval = 1 ;
#endif
return retval ;
} /* remote_upk_currthread_response */
/* -------- REMOTE_UPK-SIMPLE_ACK --------------------------------- */
/* Decode a response which is eother "OK" or "Enn"
fillin error code, fillin pkfag-1== undef, 0==nak, 1 == ack ;
return advanced packet pointer */
char * remote_upk_simple_ack(
char * buf,
int * pkflag,
int * errcode)
{
int lclerr = 0 ;
char ch = *buf++ ;
int retval = -1 ; /* Undefined ACK , a protocol error */
if (ch == 'E') /* NAK */
{
buf = unpack_byte(buf,&lclerr) ;
retval = 0 ; /* transaction failed, explicitly */
}
else
if ((ch == 'O') && (*buf++ == 'K')) /* ACK */
retval = 1 ; /* transaction succeeded */
*pkflag = retval ;
*errcode = lclerr ;
return buf ;
} /* remote-upk_simple_ack */
/* -------- PACK_THREADALIVE_REQUEST ------------------------------- */
char * pack_threadalive_request(
char * buf,
threadref * threadid)
{
*buf++ = 'T' ;
buf = pack_threadid(buf,threadid) ;
*buf = '\0' ;
return buf ;
} /* pack_threadalive_request */
#endif /* GDB_MOCKUP */
/* ---------------------------------------------------------------------- */
/* UNIT_TESTS SUBSECTION */
/* ---------------------------------------------------------------------- */
#if UNIT_TEST
extern void output_string(char * message) ;
static char test_req[400] ;
static char t_response[400] ;
/* ----- DISPLAY_THREAD_INFO ---------------------------------------------- */
/* Use local cygmon string output utiities */
void display_thread_info(struct gdb_ext_thread_info * info)
{
output_threadid("Threadid: ",&info->threadid) ;
/* short name */
output_string("Name: ") ; output_string(info->shortname) ; output_string("\n");
/* format display state */
output_string("State: ") ; output_string(info->display) ; output_string("\n") ;
/* additional data */
output_string("other: ");output_string(info->more_display);
output_string("\n\n");
} /* display_thread_info */
/* --- CURRTHREAD-TEST -------------------------------------------- */
static int currthread_test(threadref * thread)
{
int result ;
int threadid ;
output_string("TEST: currthread\n") ;
remote_pack_currthread_request(test_req) ;
stub_pkt_currthread(test_req+2,t_response,STUB_BUF_MAX) ;
result = remote_upk_currthread_response(t_response+2, &threadid) ;
if (result)
{
output_string("PASS getcurthread\n") ;
/* FIXME: print the thread */
}
else
output_string("FAIL getcurrthread\n") ;
return result ;
} /* currthread_test */
/* ------ SETTHREAD_TEST ------------------------------------------- */
/* use a known thread from previous test */
static int setthread_test(threadref * thread)
{
int result, errcode ;
output_string("TEST: setthread\n") ;
pack_setthread_request(test_req,'p',1,thread) ;
stub_pkt_changethread(test_req,t_response,STUB_BUF_MAX) ;
remote_upk_simple_ack(t_response,&result,&errcode) ;
switch (result)
{
case 0 :
output_string("FAIL setthread\n") ;
break ;
case 1 :
output_string("PASS setthread\n") ;
break ;
default :
output_string("FAIL setthread -unrecognized response\n") ;
break ;
}
return result ;
} /* setthread_test */
/* ------ THREADACTIVE_TEST ---------------------- */
/* use known thread */
/* pack threadactive packet */
/* process threadactive packet */
/* parse threadactive response */
/* check results */
int threadactive_test(threadref * thread)
{
int result ;
int errcode ;
output_string("TEST: threadactive\n") ;
pack_threadalive_request(test_req,thread) ;
stub_pkt_thread_alive(test_req+1,t_response,STUB_BUF_MAX);
remote_upk_simple_ack(t_response,&result,&errcode) ;
switch (result)
{
case 0 :
output_string("FAIL threadalive\n") ;
break ;
case 1 :
output_string("PASS threadalive\n") ;
break ;
default :
output_string("FAIL threadalive -unrecognized response\n") ;
break ;
}
return result ;
} /* threadactive_test */
/* ------ REMOTE_GET_THREADINFO -------------------------------------- */
int remote_get_threadinfo(
threadref * threadid,
int fieldset , /* TAG mask */
struct gdb_ext_thread_info * info
)
{
int result ;
pack_threadinfo_request(test_req,fieldset,threadid) ;
stub_pkt_getthreadinfo(test_req+2,t_response,STUB_BUF_MAX) ;
result = remote_upk_thread_info_response(t_response+2,threadid,info) ;
return result ;
} /* remote_get-thrreadinfo */
static struct gdb_ext_thread_info test_info ;
static int get_and_display_threadinfo(threadref * thread)
{
int mode ;
int result ;
/* output_string("TEST: get and display threadinfo\n") ; */
mode = TAG_THREADID | TAG_EXISTS | TAG_THREADNAME
| TAG_MOREDISPLAY | TAG_DISPLAY ;
result = remote_get_threadinfo(thread,mode,&test_info) ;
if (result) display_thread_info(&test_info) ;
#if 0 /* silent subtest */
if (result)
output_string("PASS: get_and_display threadinfo\n") ;
else
output_string("FAIL: get_and_display threadinfo\n") ;
#endif
return result ;
} /* get-and-display-threadinfo */
/* ----- THREADLIST_TEST ------------------------------------------ */
#define TESTLISTSIZE 16
#define TLRSIZ 2
static threadref test_threadlist[TESTLISTSIZE] ;
static int threadlist_test(void)
{
int done, i , result_count ;
int startflag = 1 ;
int result = 1 ;
int loopcount = 0 ;
static threadref nextthread ;
static threadref echo_nextthread ;
output_string("TEST: threadlist\n") ;
done = 0 ;
while (! done)
{
if (loopcount++ > 10)
{
result = 0 ;
output_string("FAIL: Threadlist test -infinite loop-\n") ;
break ;
}
pack_threadlist_request(test_req,startflag,TLRSIZ,&nextthread) ;
startflag = 0 ; /* clear for later iterations */
stub_pkt_getthreadlist(test_req+2,t_response,STUB_BUF_MAX);
result_count = parse_threadlist_response(t_response+2,
&echo_nextthread,
&test_threadlist[0],&done) ;
if (! threadmatch(&echo_nextthread,&nextthread))
{
output_string("FAIL: threadlist did not echo arg thread\n");
result = 0 ;
break ;
}
if (result_count <= 0)
{
if (done != 0)
{ output_string("FAIL threadlist_test, failed to get list");
result = 0 ;
}
break ;
}
if (result_count > TLRSIZ)
{
output_string("FAIL: threadlist response longer than requested\n") ;
result = 0 ;
break ;
}
/* Setup to resume next batch of thread references , set nestthread */
copy_threadref(&nextthread,&test_threadlist[result_count-1]) ;
/* output_threadid("last-of-batch",&nextthread) ; */
i = 0 ;
while (result_count--)
{
if (0) /* two display alternatives */
output_threadid("truncatedisplay",&test_threadlist[i++]) ;
else
get_and_display_threadinfo(&test_threadlist[i++]) ;
}
}
if (!result)
output_string("FAIL: threadlist test\n") ;
else output_string("PASS: Threadlist test\n") ;
return result ;
} /* threadlist_test */
static threadref testthread ;
int test_thread_support(void)
{
int result = 1 ;
output_string("TESTING Thread support infrastructure\n") ;
stub_pack_Tpkt_threadid(test_req) ;
PKT_TRACE("packing the threadid -> ",test_req) ;
result &= currthread_test(&testthread) ;
result &= get_and_display_threadinfo(&testthread) ;
result &= threadlist_test() ;
result &= setthread_test(&testthread) ;
if (result)
output_string("PASS: UNITTEST Thread support\n") ;
else
output_string("FAIL: UNITTEST Thread support\n") ;
return result ;
} /* test-thread_support */
#endif /* UNIT_TEST */
// #ifdef __ECOS__
#endif // ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT...
// #endif // __ECOS__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -