📄 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_TESTextern 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 2static 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 + -