Record source file changes within a function as part of debug info.

This affects functions whose body spans multiple files due to includes, or is treated as doing so due to #line directives. ORCA/C will now generate a COP 6 instruction to record each source file change, allowing debuggers to properly track the flow of execution across files.
This commit is contained in:
Stephen Heumann 2022-02-05 18:32:11 -06:00
parent 5ac79ff36c
commit 785a6997de
7 changed files with 73 additions and 30 deletions

View File

@ -475,6 +475,8 @@ var
{----} {----}
bofPtr: ptr; {pointer to the start of sourceFile} bofPtr: ptr; {pointer to the start of sourceFile}
chPtr: ptr; {pointer to the next character in the file} chPtr: ptr; {pointer to the next character in the file}
changedSourceFile: boolean; {source file changed in function?}
debugSourceFileGS: gsosOutString; {debug source file name}
{debugType is also in SCANNER.ASM} {debugType is also in SCANNER.ASM}
debugType: (stop,break,autogo); {line number debug types} debugType: (stop,break,autogo); {line number debug types}
doingParameters: boolean; {are we processing parm definitions?} doingParameters: boolean; {are we processing parm definitions?}
@ -496,7 +498,7 @@ var
oldincludeFileGS: gsosOutString; {previous includeFile value} oldincludeFileGS: gsosOutString; {previous includeFile value}
outFileGS: gsosOutString; {keep file name} outFileGS: gsosOutString; {keep file name}
partialFileGS: gsosOutString; {partial compile list} partialFileGS: gsosOutString; {partial compile list}
sourceFileGS: gsosOutString; {debug source file name} sourceFileGS: gsosOutString; {presumed source file name}
tempList: tempPtr; {list of temp work variables} tempList: tempPtr; {list of temp work variables}
longlong0: longlong; {the value 0 as a longlong} longlong0: longlong; {the value 0 as a longlong}
longlong1: longlong; {the value 1 as a longlong} longlong1: longlong; {the value 1 as a longlong}

View File

@ -34,7 +34,8 @@
{ } { }
{ pc_lnm - line number } { pc_lnm - line number }
{ } { }
{ Gen2(pc_lnm, lc, flag) } { Gen2Name(pc_lnm, lc, flag, nil) }
{ Gen2Name(pc_lnm, lc, flag, pointer(filename)) }
{ } { }
{ Sets the current line number for the traceback facility and } { Sets the current line number for the traceback facility and }
{ debugger. This p-code should only be generated after the } { debugger. This p-code should only be generated after the }
@ -46,6 +47,10 @@
{ 1 - break point } { 1 - break point }
{ 2 - auto-go } { 2 - auto-go }
{ } { }
{ If filename is not nil, it is a pointer to a GS/OS output }
{ string giving the source file name. This is used to change }
{ the file name within a function that spans multiple files. }
{ }
{ } { }
{ pc_mov - move memory } { pc_mov - move memory }
{ } { }
@ -71,7 +76,7 @@
{ debugFlag - are we generating debug code? } { debugFlag - are we generating debug code? }
{ profileFlag - are we profiling? } { profileFlag - are we profiling? }
{ traceBack - are we doing tracebacks? } { traceBack - are we doing tracebacks? }
{ sourceFile - current source file name } { debugSourceFileGS - current source file name }
{ } { }
{ } { }
{ pc_nat - native code generation } { pc_nat - native code generation }

49
Gen.pas
View File

@ -5105,6 +5105,33 @@ end; {GenUnaryQuad}
{$segment 'gen2'} {$segment 'gen2'}
procedure GenDebugSourceFile (debugFile: gsosOutStringPtr);
{ generate debug code indicating the specified source file name }
var
i: integer; {loop/index variable}
len: integer; {length of the file name}
begin {GenDebugSourceFile}
GenNative(m_cop, immediate, 6, nil, 0);
GenNative(d_add, genaddress, stringSize, nil, stringReference);
GenNative(d_add, genaddress, stringSize, nil, stringReference+shift16);
len := debugFile^.theString.size;
if len > 255 then
len := 255;
if maxString-stringSize >= len+1 then begin
stringSpace[stringSize+1] := chr(len);
for i := 1 to len do
stringSpace[i+stringSize+1] :=
debugFile^.theString.theString[i];
stringSize := stringSize + len + 1;
end {if}
else
Error(cge3);
end; {GenDebugSourceFile}
procedure GenTree {op: icptr}; procedure GenTree {op: icptr};
{ generate code for op and its children } { generate code for op and its children }
@ -6121,6 +6148,8 @@ procedure GenTree {op: icptr};
GenCall(6); GenCall(6);
end; {if} end; {if}
if debugFlag then begin if debugFlag then begin
if op^.lab <> nil then
GenDebugSourceFile(op^.lab);
GenNative(m_cop, immediate, op^.q, nil, 0); GenNative(m_cop, immediate, op^.q, nil, 0);
GenNative(d_wrd, special, op^.r, nil, 0); GenNative(d_wrd, special, op^.r, nil, 0);
end; {if} end; {if}
@ -6425,8 +6454,6 @@ procedure GenTree {op: icptr};
var var
i: integer; {loop/index variable} i: integer; {loop/index variable}
len: integer; {length of the file name}
begin {GenNam} begin {GenNam}
{generate a call to install the name in the traceback facility} {generate a call to install the name in the traceback facility}
@ -6455,22 +6482,8 @@ procedure GenTree {op: icptr};
Error(cge3); Error(cge3);
{send the file name to the debugger} {send the file name to the debugger}
if debugFlag then begin if debugFlag then
GenNative(m_cop, immediate, 6, nil, 0); GenDebugSourceFile(@debugSourceFileGS);
GenNative(d_add, genaddress, stringSize, nil, stringReference);
GenNative(d_add, genaddress, stringSize, nil, stringReference+shift16);
len := sourceFileGS.theString.size;
if len > 255 then
len := 255;
if maxString-stringSize >= len+1 then begin
stringSpace[stringSize+1] := chr(len);
for i := 1 to len do
stringSpace[i+stringSize+1] := sourceFileGS.theString.theString[i];
stringSize := stringSize + len + 1;
end {if}
else
Error(cge3);
end; {if}
end; {GenNam} end; {GenNam}

View File

@ -406,6 +406,28 @@ NextToken; {remove the rbracech token}
end; {EndCompoundStatement} end; {EndCompoundStatement}
procedure RecordLineNumber (lineNumber: integer);
{ generate debug code to record the line number as specified }
var
newSourceFileGS: gsosOutStringPtr;
begin {RecordLineNumber}
if (lastLine <> lineNumber) or changedSourceFile then begin
lastLine := lineNumber;
if changedSourceFile then begin
newSourceFileGS := pointer(Malloc(sizeof(gsosOutString)));
newSourceFileGS^ := sourceFileGS;
Gen2Name(pc_lnm, lineNumber, ord(debugType), pointer(newSourceFileGS));
changedSourceFile := false;
end {if}
else
Gen2Name(pc_lnm, lineNumber, ord(debugType), nil);
end; {if}
end; {RecordLineNumber}
procedure Statement; procedure Statement;
{ handle a statement } { handle a statement }
@ -941,10 +963,7 @@ begin {Statement}
{if trace names are enabled and a line # is due, generate it} {if trace names are enabled and a line # is due, generate it}
if traceBack or debugFlag then if traceBack or debugFlag then
if nameFound or debugFlag then if nameFound or debugFlag then
if lastLine <> lineNumber then begin RecordLineNumber(lineNumber);
lastLine := lineNumber;
Gen2(pc_lnm, lineNumber, ord(debugType));
end; {if}
{handle the statement} {handle the statement}
case token.kind of case token.kind of
@ -3874,8 +3893,10 @@ if isFunction then begin
if traceBack or profileFlag then begin if traceBack or profileFlag then begin
if traceBack then if traceBack then
nameFound := true; nameFound := true;
debugSourceFileGS := sourceFileGS;
GenPS(pc_nam, variable^.name); GenPS(pc_nam, variable^.name);
end; {if} end; {if}
changedSourceFile := false;
nextPdisp := 0; {assign displacements to the parameters} nextPdisp := 0; {assign displacements to the parameters}
if not fnType^.isPascal then begin if not fnType^.isPascal then begin
tlp := lp; tlp := lp;
@ -4582,10 +4603,7 @@ if variable^.class <> staticsy then begin
if traceBack or debugFlag then if traceBack or debugFlag then
if nameFound or debugFlag then if nameFound or debugFlag then
if (statementList <> nil) and not statementList^.doingDeclaration then if (statementList <> nil) and not statementList^.doingDeclaration then
if lastLine <> line then begin RecordLineNumber(line);
lastLine := line;
Gen2(pc_lnm, line, ord(debugType));
end; {if}
Initialize(variable, 0, variable^.itype); Initialize(variable, 0, variable^.itype);
end; {if} end; {if}
end; {AutoInit} end; {AutoInit}

View File

@ -577,6 +577,9 @@ lb4 lda [p1],Y
dey dey
bpl lb4 bpl lb4
long M long M
! changedSourceFile := true;
lda #1
sta changedSourceFile
! lineNumber := fp^.lineNumber; ! lineNumber := fp^.lineNumber;
ldy #4+maxPath+4+maxPath+4 ldy #4+maxPath+4+maxPath+4
lda [fp],Y lda [fp],Y

View File

@ -2170,6 +2170,7 @@ if gotName then begin {read the file name from the line}
includeFileGS.theString.theString := workString; includeFileGS.theString.theString := workString;
includeFileGS.theString.size := length(workString); includeFileGS.theString.size := length(workString);
sourceFileGS := includeFileGS; sourceFileGS := includeFileGS;
changedSourceFile := true;
ReadFile; {read the file} ReadFile; {read the file}
chPtr := bofPtr; {set the start, end pointers} chPtr := bofPtr; {set the start, end pointers}
eofPtr := pointer(ord4(bofPtr)+ffDCBGS.fileLength); eofPtr := pointer(ord4(bofPtr)+ffDCBGS.fileLength);
@ -3069,6 +3070,7 @@ if ch in ['a','d','e','i','l','p','u','w'] then begin
sourceFileGS.theString.size := token.sval^.length-1; sourceFileGS.theString.size := token.sval^.length-1;
if sourceFileGS.theString.size > 255 then if sourceFileGS.theString.size > 255 then
sourceFileGS.theString.size := 255; sourceFileGS.theString.size := 255;
changedSourceFile := true;
NextToken; NextToken;
end; {if} end; {if}
if token.kind <> eolsy then if token.kind <> eolsy then

View File

@ -1744,7 +1744,7 @@ int foo(int[42]);
(Devin Reade) (Devin Reade)
177. The name of the current source file was not updated when processing an #include or #append. As a result, uses of the __FILE__ macro within an include file would not give the name of that file, and functions within an include file would not have the proper file name recorded in their debugging information. 177. The name of the current source file was not updated when processing an #include or #append. As a result, uses of the __FILE__ macro within an include file would not give the name of that file, and functions (or portions of functions) within an include file would not have the proper file name recorded in their debugging information.
-- Bugs from C 2.1.0 that have been fixed ----------------------------------- -- Bugs from C 2.1.0 that have been fixed -----------------------------------