364 lines
8.2 KiB
Plaintext
364 lines
8.2 KiB
Plaintext
#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 (Jiffies<j);
|
|
Fs->double_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] && line<max)
|
|
line++;
|
|
return tempd->body[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) &&
|
|
rip<IDELineAdd(tempd,line+1))
|
|
return line;
|
|
}
|
|
}
|
|
}
|
|
temph=temph->next;
|
|
}
|
|
}
|
|
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->rip<u0 || Fs->rip>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 ""
|
|
|