Skip to content

Commit

Permalink
Merge pull request #6947 from rainers/issue17559
Browse files Browse the repository at this point in the history
fix issue 17559 - [REG2.073.0] Wrong line number in stack trace
  • Loading branch information
braddr authored Nov 18, 2017
2 parents ad70d70 + 90d4bfa commit c6a948b
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 16 deletions.
6 changes: 3 additions & 3 deletions src/ddmd/backend/cgcod.c
Original file line number Diff line number Diff line change
Expand Up @@ -2620,16 +2620,16 @@ void codelem(CodeBuilder& cdb,elem *e,regm_t *pretregs,bool constflag)
if (!constflag && *pretregs & (mES | ALLREGS | mBP | XMMREGS) & ~regcon.mvar)
*pretregs &= ~regcon.mvar; /* can't use register vars */

if (configv.addlinenumbers && e->Esrcpos.Slinnum)
cdb.genlinnum(e->Esrcpos);

unsigned op = e->Eoper;
if (e->Ecount && e->Ecount != e->Ecomsub) // if common subexp
{
comsub(cdb,e,pretregs);
goto L1;
}

if (configv.addlinenumbers && e->Esrcpos.Slinnum)
cdb.genlinnum(e->Esrcpos);

switch (op)
{
default:
Expand Down
39 changes: 26 additions & 13 deletions test/d_do_test.d
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ struct EnvData
bool coverage_build;
}

bool findTestParameter(string file, string token, ref string result)
bool findTestParameter(const ref EnvData envData, string file, string token, ref string result)
{
auto tokenStart = std.string.indexOf(file, token);
if (tokenStart == -1) return false;
Expand All @@ -99,14 +99,27 @@ bool findTestParameter(string file, string token, ref string result)
//writeln("found ", token, " in line: '", file[tokenStart .. tokenStart+lineEnd], "'");

result = strip(file[tokenStart+token.length .. tokenStart+lineEnd]);
// filter by OS specific setting (os1 os2 ...)
if (result.length > 0 && result[0] == '(')
{
auto close = std.string.indexOf(result, ")");
if (close >= 0)
{
string[] oss = split(result[1 .. close], " ");
if (oss.canFind(envData.os))
result = result[close + 1..$];
else
result = null;
}
}
// skips the :, if present
if (result.length > 0 && result[0] == ':')
result = strip(result[1 .. $]);

//writeln("arg: '", result, "'");

string result2;
if (findTestParameter(file[tokenStart+lineEnd..$], token, result2))
if (findTestParameter(envData, file[tokenStart+lineEnd..$], token, result2))
result ~= " " ~ result2;

return true;
Expand Down Expand Up @@ -165,18 +178,18 @@ bool gatherTestParameters(ref TestArgs testArgs, string input_dir, string input_
{
string file = cast(string)std.file.read(input_file);

findTestParameter(file, "REQUIRED_ARGS", testArgs.requiredArgs);
findTestParameter(envData, file, "REQUIRED_ARGS", testArgs.requiredArgs);
if(envData.required_args.length)
testArgs.requiredArgs ~= " " ~ envData.required_args;
replaceResultsDir(testArgs.requiredArgs, envData);

if (! findTestParameter(file, "PERMUTE_ARGS", testArgs.permuteArgs))
if (! findTestParameter(envData, file, "PERMUTE_ARGS", testArgs.permuteArgs))
{
if (testArgs.mode == TestMode.RUN)
testArgs.permuteArgs = envData.all_args;

string unittestJunk;
if(!findTestParameter(file, "unittest", unittestJunk))
if(!findTestParameter(envData, file, "unittest", unittestJunk))
testArgs.permuteArgs = replace(testArgs.permuteArgs, "-unittest", "");
}
replaceResultsDir(testArgs.permuteArgs, envData);
Expand All @@ -192,25 +205,25 @@ bool gatherTestParameters(ref TestArgs testArgs, string input_dir, string input_
// clean up extra spaces
testArgs.permuteArgs = strip(replace(testArgs.permuteArgs, " ", " "));

findTestParameter(file, "EXECUTE_ARGS", testArgs.executeArgs);
findTestParameter(envData, file, "EXECUTE_ARGS", testArgs.executeArgs);
replaceResultsDir(testArgs.executeArgs, envData);

string extraSourcesStr;
findTestParameter(file, "EXTRA_SOURCES", extraSourcesStr);
findTestParameter(envData, file, "EXTRA_SOURCES", extraSourcesStr);
testArgs.sources = [input_file];
// prepend input_dir to each extra source file
foreach(s; split(extraSourcesStr))
testArgs.sources ~= input_dir ~ "/" ~ s;

string extraCppSourcesStr;
findTestParameter(file, "EXTRA_CPP_SOURCES", extraCppSourcesStr);
findTestParameter(envData, file, "EXTRA_CPP_SOURCES", extraCppSourcesStr);
testArgs.cppSources = [];
// prepend input_dir to each extra source file
foreach(s; split(extraCppSourcesStr))
testArgs.cppSources ~= s;

string extraObjcSourcesStr;
auto objc = findTestParameter(file, "EXTRA_OBJC_SOURCES", extraObjcSourcesStr);
auto objc = findTestParameter(envData, file, "EXTRA_OBJC_SOURCES", extraObjcSourcesStr);

if (objc && !envData.dobjc)
return false;
Expand All @@ -227,18 +240,18 @@ bool gatherTestParameters(ref TestArgs testArgs, string input_dir, string input_
//writeln ("sources: ", testArgs.sources);

// COMPILE_SEPARATELY can take optional compiler switches when link .o files
testArgs.compileSeparately = findTestParameter(file, "COMPILE_SEPARATELY", testArgs.requiredArgsForLink);
testArgs.compileSeparately = findTestParameter(envData, file, "COMPILE_SEPARATELY", testArgs.requiredArgsForLink);

string disabledPlatformsStr;
findTestParameter(file, "DISABLED", disabledPlatformsStr);
findTestParameter(envData, file, "DISABLED", disabledPlatformsStr);
testArgs.disabledPlatforms = split(disabledPlatformsStr);

findOutputParameter(file, "TEST_OUTPUT", testArgs.compileOutput, envData.sep);

findOutputParameter(file, "GDB_SCRIPT", testArgs.gdbScript, envData.sep);
findTestParameter(file, "GDB_MATCH", testArgs.gdbMatch);
findTestParameter(envData, file, "GDB_MATCH", testArgs.gdbMatch);

if (findTestParameter(file, "POST_SCRIPT", testArgs.postScript))
if (findTestParameter(envData, file, "POST_SCRIPT", testArgs.postScript))
testArgs.postScript = replace(testArgs.postScript, "/", to!string(envData.sep));

return true;
Expand Down
84 changes: 84 additions & 0 deletions test/runnable/test17559.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// REQUIRED_ARGS: -g
// REQUIRED_ARGS(linux freebsd): -L-export-dynamic
// PERMUTE_ARGS:
// DISABLED: osx

import core.stdc.stdio;

void main()
{
fun(1);
fun(2);
fun(3);
#line 30
fun(4);

foo(1, 10);
foo(2, 10);
foo(3, 10);
#line 40
foo(4, 10);
}

void fun(int n, int defParam = 10)
{
try
{
if (n == 4)
throw new Exception("fun");
}
catch(Exception e)
{
string s = e.toString();
printf("%.*s\n", cast(int)s.length, s.ptr);
int line = lineInMain(e.toString());
assert(line >= 30 && line <= 32); // return address might be next statement
}
}

void foo(int n, int m)
{
try
{
if (n == 4)
throw new Exception("foo");
}
catch(Exception e)
{
string s = e.toString();
printf("%.*s\n", cast(int)s.length, s.ptr);
int line = lineInMain(e.toString());
assert(line >= 40 && line <= 41); // return address might be next statement
}
}

int lineInMain(string msg)
{
// find line number of _Dmain in stack trace
// on linux: file.d:line _Dmain [addr]
// on windows: addr in _Dmain at file.d(line)
int line = 0;
bool mainFound = false;
for (size_t pos = 0; pos + 6 < msg.length; pos++)
{
if (msg[pos] == '\n')
{
line = 0;
mainFound = false;
}
else if ((msg[pos] == ':' || msg[pos] == '(') && line == 0)
{
for (pos++; pos < msg.length && msg[pos] >= '0' && msg[pos] <= '9'; pos++)
line = line * 10 + msg[pos] - '0';
if (line > 0 && mainFound)
return line;
}
else if (msg[pos .. pos + 6] == "_Dmain" || msg[pos .. pos + 6] == "D main")
{
mainFound = true;
if (line > 0 && mainFound)
return line;
}
}
return 0;
}

0 comments on commit c6a948b

Please sign in to comment.