#help_index "Debugging" ClassStruct *DbgFindFun(Ltf *l,I8 line_offset=0) { I1 st[256],*filename=l->filename.name; I8 line=l->cur_entry->y+1+line_offset; U8 i; SysHashEntry *temph; SysHashTable *h=Fs->hash_table; ClassStruct *tempc; DbgInfo *tempd; while (h) { for (i=0;i<=h->mask;i++) { temph=h->body[i]; while (temph) { if (temph->type&HTT_FUNCTION) { tempc=temph; if (tempd=tempc->debug) { StrCpy(st,tempc->source_link); RemoveFirstSeg(st,":"); RemoveLastSeg(st,","); if (!StrCmp(st,filename)) { if (line>=tempd->min_line && line<=tempd->max_line) return tempc; } } } temph=temph->next; } } h=h->next; } return NULL; } void WatchLocals() { BoolU4 old_preempt=Preempt(OFF); TssStruct *tss=Fs->parent_tss,*dbg_tss=tss->dbg_tss; Ltf *swap,*l; ClassStruct *tempc,*tempc1; U8 j,sc,ch; void **rbp,**ptr; I8 offset,ip; Fs->double_buf_cur_ltf=LtfNew; while (TRUE) { if (!(dbg_tss=tss->dbg_tss)) Exit; if (ScanKey(&ch,&sc,TRUE)) { j=Jiffies+JIFFY_FREQ*5; LtfDel(Fs->double_buf_cur_ltf); Fs->double_buf_cur_ltf=NULL; do { if (ch==CH_CTRLQ || ch==CH_ESC) Exit; if (ScanKey(&ch,&sc,TRUE)) j=Jiffies+JIFFY_FREQ*5; WinSync; } while (Jiffiesdouble_buf_cur_ltf=LtfNew; } else { LtfDel(Fs->cur_ltf); Fs->cur_ltf=LtfNew; if (l=dbg_tss->cur_ltf) { if (tempc=DbgFindFun(l,0)) { PutS("$$WW,1$$"); rbp=tss->rbp; ip=tss->rip; do { tempc1=FindPSect(ip,&offset); break; //TODO: load reg variables for higher level subroutines if (tempc==tempc1) break; else { if (rbp>=*rbp) break; ptr=rbp+8; rbp=*rbp; ip=*ptr; if (!CheckOnStk(rbp,tss)) break; } } while (TRUE); if (tempc==tempc1) FunRep(tempc->str,rbp,2,tss); } } swap=Fs->double_buf_cur_ltf; Fs->double_buf_cur_ltf=Fs->cur_ltf; Fs->cur_ltf=swap; WinSync; } } LtfDel(Fs->double_buf_cur_ltf); Fs->double_buf_cur_ltf=NULL; Preempt(old_preempt); } public void IDE(I1 *filename) //Spawns a child process which has //access to parents symbols. Can be used //to debug parent. { TssStruct *tss; I1 *fn1=DefaultExtension(filename,"CPZ"), *fn2=AbsoluteFileName(fn1); if (PopUpCancelOk("$$BK,1$$$$FG,RED$$LoseThos IDE Debugger$$FG$$$$BK,0$$\r\n" "Do not use this on files that run when included.\r\n" "\r\nTo use:\r\n" " 1) Set a break-point in the editor window.\r\n" " 2) Run program from command line.\r\n\r\n" "$$FG,GREEN$$F5$$FG$$\t\tGo\r\n" "$$FG,GREEN$$SHIFT-F5$$FG$$\tStep\r\n" "$$FG,GREEN$$F9$$FG$$\t\tToggle Break Point\r\n" "$$FG,GREEN$$SHIFT-F9$$FG$$\tClear All Break Points\r\n" )) { if (!Fs->dbg_tss) { Fs->win_top=2; Fs->win_bottom=TEXT_ROWS-2; Fs->win_left=1; Fs->win_right=TEXT_COLS>>1-1; tss=Spawn(&UserCmdLine,"Debug Task",Fs); WaitTskIdle(tss); tss->win_top=12; tss->win_bottom=TEXT_ROWS-2; tss->win_left=TEXT_COLS>>1+1; tss->win_right=TEXT_COLS-2; XTalk(tss,"Edit(\"%s\");\r",fn2); Fs->dbg_tss=tss; tss=Spawn(&UserCmdLine,"Watch Task",Fs); WaitTskIdle(tss); tss->win_top=2; tss->win_bottom=10; tss->win_left=TEXT_COLS>>1+1; tss->win_right=TEXT_COLS-2; XTalk(tss,"WatchLocals;\r"); ExecuteFile(fn2); } Free(fn1); Free(fn2); } } #help_index "Debugging/Breakpoints" I8 IDELineAdd(DbgInfo *tempd,I8 line) { I8 max=tempd->max_line-tempd->min_line; line-=tempd->min_line; if (line<0) return IDELineAdd(tempd,tempd->min_line); while (!tempd->body[line] && linebody[line]; } I8 IDERIPLineNum(Ltf *l,void *rip) { I1 st[256],*filename=l->filename.name; I8 line; SysHashEntry *temph; SysHashTable *h=Fs->hash_table; ClassStruct *tempc; I8 i; DbgInfo *tempd; while (h) { for (i=0;i<=h->mask;i++) { temph=h->body[i]; while (temph) { if (temph->type&HTT_FUNCTION) { tempc=temph; if (tempd=tempc->debug) { StrCpy(st,tempc->source_link); RemoveFirstSeg(st,":"); RemoveLastSeg(st,","); if (!StrCmp(st,filename)) { for (line=tempd->min_line;line<=tempd->max_line;line++) if (rip>=IDELineAdd(tempd,line) && ripnext; } } h=h->next; } return -1; } void IDESetStepRange(Ltf *l) { I1 st[256],*filename=l->filename.name; I8 line=l->cur_entry->y+1; SysHashEntry *temph; SysHashTable *h=Fs->hash_table; ClassStruct *tempc; I8 i; DbgInfo *tempd; while (h) { for (i=0;i<=h->mask;i++) { temph=h->body[i]; while (temph) { if (temph->type&HTT_FUNCTION) { tempc=temph; if (tempd=tempc->debug) { StrCpy(st,tempc->source_link); RemoveFirstSeg(st,":"); RemoveLastSeg(st,","); if (!StrCmp(st,filename)) { if (line>=tempd->min_line && line<=tempd->max_line) { Fs->user_data0=IDELineAdd(tempd,line); Fs->user_data1=IDELineAdd(tempd,line+1); return; } } } } temph=temph->next; } } h=h->next; } } void IDEToggleBpt(Ltf *l) { //F9 I1 st[256],*filename=l->filename.name; I8 line=l->cur_entry->y+1; SysHashEntry *temph; SysHashTable *h=Fs->hash_table; ClassStruct *tempc; I8 i,a; DbgInfo *tempd; LtfEntry *ll; while (h) { for (i=0;i<=h->mask;i++) { temph=h->body[i]; while (temph) { if (temph->type&HTT_FUNCTION) { tempc=temph; if (tempd=tempc->debug) { StrCpy(st,tempc->source_link); RemoveFirstSeg(st,":"); RemoveLastSeg(st,","); if (!StrCmp(st,filename)) { if (line>=tempd->min_line && line<=tempd->max_line) { a=IDELineAdd(tempd,line); ll=l->cur_entry; while (ll->last->btype!=LTFT_CR && ll->last->btype!=LTFT_SOFT_CR && ll->last!=l) ll=ll->last; l->cur_entry=ll; l->cur_data_col=ll->min_col; if (!RBpt(Fs->parent_tss,a)) { SBpt(Fs->parent_tss,a,SBPTF_BPT); Auto("$$BP$$"); } else { if (ll->btype==LTFT_BPT) { l->cur_entry=ll->next; l->cur_data_col=l->cur_entry->min_col; LtfDelEntry(l,ll); } } LtfGotoLineNum(l,line); return; } } } } temph=temph->next; } } h=h->next; } } void IDEClearAllBpts(Ltf *l) { //SHIFT-F9 LtfEntry *ll,*ll2; CBpt(Fs->parent_tss); ll=l->dummy.next; while (ll!=l) { ll2=ll->next; if (ll->btype==LTFT_BPT) { if (l->cur_entry==ll) { l->cur_entry=ll->next; l->cur_data_col=l->cur_entry->min_col; } LtfDelEntry(l,ll); } ll=ll2; } } void IDEGo() //Continue after breakpoint { //F5 TssStruct *tss=Fs->parent_tss; void *rip=&tss->rip; if (!Btr(&tss->task_flags,TSSf_DISABLE_BPTS)) { *rip-=1; if (!DBpt(tss,*rip)) *rip+=1; } Fs->user_data0=0; Fs->user_data1=0; Btr(&tss->rflags,8); Btr(&tss->task_flags,TSSf_SUSPENDED); } void IDEStep(Ltf *l) //Single step { //SHIFT-F5 TssStruct *tss=Fs->parent_tss; void *rip=&tss->rip; I8 line=IDERIPLineNum(l,*rip); if (!Bts(&tss->task_flags,TSSf_DISABLE_BPTS)) { *rip-=1; if (!DBpt(tss,*rip)) *rip+=1; } if (line>0) { LtfGotoLineNum(l,line); IDESetStepRange(l); } else { Fs->user_data0=0; Fs->user_data1=0; } Bts(&tss->rflags,8); Btr(&tss->task_flags,TSSf_SUSPENDED); } void IDESetLineNum(Ltf *l) { //SHIFT-F8 TssStruct *tss=Fs->parent_tss; I8 line=IDERIPLineNum(l,tss->rip); if (line>0) LtfGotoLineNum(l,line); } void IDEResumeDbg() { TssStruct *dbg=Fs->dbg_tss; I8 u0=dbg->user_data0,u1=dbg->user_data1; if (!u0 || (Fs->riprip>u1) || Fs->rip==u1 && u1!=u0) { WinToTop(dbg); QueueMsg(dbg,NULL,MSG_KEY_DOWN,0,SCF_SHIFT+SC_F8,0); } else Btr(&Fs->task_flags,TSSf_SUSPENDED); } ext[EXT_RESUME_DBG]=&IDEResumeDbg; #help_index ""