dmd icon indicating copy to clipboard operation
dmd copied to clipboard

fix Issue 17494 - Do not execute scope(...) if an Error exception has…

Open WalterBright opened this issue 8 years ago • 30 comments

… been thrown

fix 17494

This is an enhancement, see https://issues.dlang.org/show_bug.cgi?id=17494

It's also a regression fix.

WalterBright avatar Jun 12 '17 00:06 WalterBright

Thanks for your pull request, @WalterBright!

Bugzilla references

Auto-close Bugzilla Severity Description
17494 enhancement Do not execute scope(...) if an Error exception has been thrown

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + dmd#6896"

dlang-bot avatar Jun 12 '17 00:06 dlang-bot

fix 17493

This should be in the commit message as well, so it's picked up by @dlang-bot.

CyberShadow avatar Jun 12 '17 01:06 CyberShadow

This should be in the commit message as well, so it's picked up by @dlang-bot.

I don't know what dlang-bot looks for, everything I try fails. I tried "fix 17493" and "fix issue 17493", to no avail.

WalterBright avatar Jun 12 '17 03:06 WalterBright

I don't know what dlang-bot looks for, everything I try fails. I tried "fix 17493" and "fix issue 17493", to no avail.

Are you editing the commit message (when creating the git commit on your computer), or the pull request description (in your web browser)? We're talking about the former.

CyberShadow avatar Jun 12 '17 03:06 CyberShadow

Are you editing the commit message (when creating the git commit on your computer), or the pull request description (in your web browser)? We're talking about the former.

I think I mention the link to the explanation almost daily ;-) https://github.com/dlang-bots/dlang-bot

And in dubito, try it online

Of course you can also execute the D function yourself:

import std.algorithm, std.conv, std.range, std.string;
import std.format : format;

auto matchIssueRefs(string message)
{
    import std.regex;

    static auto matchToRefs(M)(M m)
    {
        enum splitRE = regex(`[^\d]+`); // ctRegex throws a weird error in unittest compilation
        auto closed = !m.captures[1].empty;
        return m.captures[5].stripRight.splitter(splitRE)
            .filter!(id => !id.empty) // see #6
            .map!(id => IssueRef(id.to!int, closed));
    }

    // see https://github.com/github/github-services/blob/2e886f407696261bd5adfc99b16d36d5e7b50241/lib/services/bugzilla.rb#L155
    enum issueRE = ctRegex!(`((close|fix|address)e?(s|d)? )?(ticket|bug|tracker item|issue)s?:? *([\d ,\+&#and]+)`, "i");
    return message.matchAll(issueRE).map!matchToRefs.joiner;
}

struct IssueRef { int id; bool fixed; }

void main()
{
   import std.stdio;
   matchIssueRefs("fix Issue 17494 17493 - Do not execute scope(...) if an Error ").writeln;
}

wilzbach avatar Jun 12 '17 03:06 wilzbach

Cool! A promise made by the spec finally fulfilled. This will allow smaller and faster functions for most cases.

We'll need a changelog entry as well.

andralex avatar Jun 12 '17 17:06 andralex

We're talking about the former.

It used to work by looking at the github comments.

WalterBright avatar Jun 12 '17 18:06 WalterBright

Hmm #6816 also broke D-YAML, but this bugfix PR doesn't seem to fix the regression observed in D-YAML.

(working on a reduction)

wilzbach avatar Jun 12 '17 20:06 wilzbach

It used to work by looking at the github comments.

It never did that, we want our information in git to be available for tooling, not locked into a proprietary platform.

MartinNowak avatar Jun 17 '17 08:06 MartinNowak

We're about to release 2.075.0 soon, so let's not try to counter a risky change with yet another one (changing all scope (failure) catch handlers from Throwable to Exception). Given the amount of fallout, I'd rather revert #6816 for now and revisit it for the next major version (2.076 if we don't yet change the version scheme).

MartinNowak avatar Jun 17 '17 08:06 MartinNowak

I agree it's a risky change.

WalterBright avatar Jun 17 '17 08:06 WalterBright

Apparently hangs some test in dmd's test suite.

MartinNowak avatar Oct 05 '17 21:10 MartinNowak

@WalterBright I'll approve pending the unittester, I suppose this needs a bit of work.

andralex avatar Oct 15 '17 14:10 andralex

removing the auto-merge flag because the tests don't pass and in fact are stalling resulting in abnormally long builds that must hit timeouts to end.

braddr avatar Oct 16 '17 22:10 braddr

@WalterBright Is this PR still needed? The test case in https://issues.dlang.org/show_bug.cgi?id=17493 compiles fine, and https://issues.dlang.org/show_bug.cgi?id=17494 is marked RESOLVED.

JinShil avatar Jan 29 '18 07:01 JinShil

Probably still a good idea to add the test case to the test suite then.

wilzbach avatar Jan 29 '18 08:01 wilzbach

Probably still a good idea to add the test case to the test suite then.

It looks like the test case was added in #6913

JinShil avatar Jan 29 '18 08:01 JinShil

@WalterBright please review and close

andralex avatar Jan 29 '18 14:01 andralex

I don't see any reason to keep this open.

JinShil avatar Feb 03 '18 13:02 JinShil

cc @WalterBright sup

andralex avatar Feb 03 '18 13:02 andralex

This PR is still the right thing to do. Attempting to unwind when an Error is thrown is a bad idea, and leads to undefined behavior. Essentially, code which relies on such unwinding needs to be fixed.

WalterBright avatar Feb 03 '18 21:02 WalterBright

This appears to break code in druntime

timelimit -t 10 generated/linux/release/32/unittest/test_runner rt.minfo
core.exception.InvalidMemoryOperationError@src/core/exception.d(702): Invalid memory operation
----------------
uncaught exception
core.exception.InvalidMemoryOperationError@src/core/exception.d(702): Invalid memory operation
----------------

JinShil avatar Feb 03 '18 23:02 JinShil

ping @ibuclaw I guess if DMD now starts to really employ the 'no cleaning up after throwing an error' rule and druntime and other libraries are fixed, we could finally turn such throw statements into a simple abort in GDC and map nothrow to TREE_NOTHROW for better optimizations?

(IIRC trying to unwind if we use TREE_NOTHROW is a bad idea, I think it crashes the unwinder on ARM. So a clean approach would probably have to give up on unwinding and use an abort-solution).

jpf91 avatar Feb 04 '18 10:02 jpf91

@jpf91 - I think that a program crashing abnormally because something threw inside a nothrow function, although may not be seen as desirable, should be considered acceptable behaviour in release mode.

ibuclaw avatar Feb 04 '18 11:02 ibuclaw

Also OK, I don't have a strong opinion on that. Although an abort could make debugging easier than a crash somewhere in the unwind logic. OTOH architectures which can unwind from nothrow functions benefit from a stack trace...

jpf91 avatar Feb 04 '18 11:02 jpf91

If the agreement is that no unwinding should happen if an Error is thrown, then the standard exception handling mechanism should not be used: by throwing an exception, (some) unwinding will always happen...

JohanEngelen avatar Jan 22 '19 14:01 JohanEngelen

What is the status of the issue ? It's marked closed. Can this PR be as well ? Also note that the test case has never failed to compile.

rdmd playground.d

All versions: Success and no output

ghost avatar Sep 05 '20 09:09 ghost

What is the status of the issue ? It's marked closed. Can this PR be as well ?

Commented on the issue, scope(exit) is still executed for Errors.

Also note that the test case has never failed to compile.

Not for official releases - the changes from -preview=dtorfields were initiallly enabled by default but hidden as a preview because of the code breakage IIRC.


A small test case;

// nothrow: // Uncomment this to make the test pass

void main()
{
    bool caught;

    try
        foo();
    catch (Error)
        caught = true;

    assert(caught);
    assert(counter == 0);
}

__gshared int counter = 0;

void foo()
{
    scope (exit) counter++;
    throwError();
}

void throwError()
{
    throw new Error("");
}

MoonlightSentinel avatar Sep 05 '20 14:09 MoonlightSentinel

@WalterBright tests have failed.

12345swordy avatar Oct 24 '20 17:10 12345swordy

The tests all fail because the test suite hangs and times out. There's no clue which test hung.

WalterBright avatar Jul 16 '22 23:07 WalterBright