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}
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: (stop,break,autogo); {line number debug types}
doingParameters: boolean; {are we processing parm definitions?}
@ -496,7 +498,7 @@ var
oldincludeFileGS: gsosOutString; {previous includeFile value}
outFileGS: gsosOutString; {keep file name}
partialFileGS: gsosOutString; {partial compile list}
sourceFileGS: gsosOutString; {debug source file name}
sourceFileGS: gsosOutString; {presumed source file name}
tempList: tempPtr; {list of temp work variables}
longlong0: longlong; {the value 0 as a longlong}
longlong1: longlong; {the value 1 as a longlong}

View File

@ -34,7 +34,8 @@
{ }
{ 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 }
{ debugger. This p-code should only be generated after the }
@ -46,6 +47,10 @@
{ 1 - break point }
{ 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 }
{ }
@ -71,7 +76,7 @@
{ debugFlag - are we generating debug code? }
{ profileFlag - are we profiling? }
{ traceBack - are we doing tracebacks? }
{ sourceFile - current source file name }
{ debugSourceFileGS - current source file name }
{ }
{ }
{ pc_nat - native code generation }

49
Gen.pas
View File

@ -5105,6 +5105,33 @@ end; {GenUnaryQuad}
{$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};
{ generate code for op and its children }
@ -6121,6 +6148,8 @@ procedure GenTree {op: icptr};
GenCall(6);
end; {if}
if debugFlag then begin
if op^.lab <> nil then
GenDebugSourceFile(op^.lab);
GenNative(m_cop, immediate, op^.q, nil, 0);
GenNative(d_wrd, special, op^.r, nil, 0);
end; {if}
@ -6425,8 +6454,6 @@ procedure GenTree {op: icptr};
var
i: integer; {loop/index variable}
len: integer; {length of the file name}
begin {GenNam}
{generate a call to install the name in the traceback facility}
@ -6455,22 +6482,8 @@ procedure GenTree {op: icptr};
Error(cge3);
{send the file name to the debugger}
if debugFlag then begin
GenNative(m_cop, immediate, 6, nil, 0);
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}
if debugFlag then
GenDebugSourceFile(@debugSourceFileGS);
end; {GenNam}

View File

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

View File

@ -577,6 +577,9 @@ lb4 lda [p1],Y
dey
bpl lb4
long M
! changedSourceFile := true;
lda #1
sta changedSourceFile
! lineNumber := fp^.lineNumber;
ldy #4+maxPath+4+maxPath+4
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.size := length(workString);
sourceFileGS := includeFileGS;
changedSourceFile := true;
ReadFile; {read the file}
chPtr := bofPtr; {set the start, end pointers}
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;
if sourceFileGS.theString.size > 255 then
sourceFileGS.theString.size := 255;
changedSourceFile := true;
NextToken;
end; {if}
if token.kind <> eolsy then

View File

@ -1744,7 +1744,7 @@ int foo(int[42]);
(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 -----------------------------------