Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: emscripten-core/emscripten
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: rbit/emscripten
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 1 commit
  • 1 file changed
  • 1 contributor

Commits on Oct 8, 2016

  1. Fix Exception Handling Leak and Crash

    This patch fixes two issues in the exception handling backend
    (transforms actual results reported below to expected results
    reported below).
    
    Environment:
      Branch: master
      Emcc -v: emcc (Emscripten gcc/clang-like replacement + linker
               emulating GNU ld) 1.36.0
               clang version 3.9.0
               (https://github.com/kripken/emscripten-fastcomp-clang/
               271ce598c3d1fe74efadc254f5be1b57edea9f41)
               (https://github.com/kripken/emscripten-fastcomp/
               61acfb230665464544f2e8db292f8999fc3c628c)
               (emscripten 1.36.0 : 1.36.0)
               Target: x86_64-apple-darwin16.0.0
               Thread model: posix
               InstalledDir: /Users/ray/src/gm/emsdk_portable/clang/
               fastcomp/build_master_64/bin
               INFO:root:(Emscripten: Running sanity checks)
    
    Issue 1: Re-thrown exceptions leak (and their destructors are
             not invoked)
    
    Repro:
    
     #include <iostream>
    
    struct NeedsCleanUp
    {
        NeedsCleanUp()
        {
            std::cout << "Creating cleanup item" << std::endl;
        }
    
        ~NeedsCleanUp()
        {
            std::cout << "Destroying cleanup item" << std::endl;
        }
    };
    
    int main(int argc, char* argv[])
    {
        try
        {
            try
            {
                throw NeedsCleanUp {};
            }
            catch (...)
            {
                throw;  // rethrow causes leak
            }
        }
        catch (...)
        {
        }
    
        return 0;
    }
    
    Build and run:
    em++ -g -std=c++11 --emrun -s EXCEPTION_DEBUG=0 -o exc1.html exc1.cpp
    emrun --browser chrome exc1.html
    
    ACTUAL RESULT:
    
    pre-main prep time: 23 ms
    Creating cleanup item
    
    ACTUAL RESULT WITH EXCEPTION DEBUG:
    
    pre-main prep time: 25 ms
    Creating cleanup item
    Compiled code throwing an exception, 5267520,8,357
    can_catch on 5267520
    cxa_begin_catch 5267520,stack,5267520
    addref 5267520
    Compiled code RE-throwing an exception, popped 5267520,5267520,stack,
    can_catch on 5267520
    cxa_begin_catch 5267520,stack,5267520
    addref 5267520
    cxa_end_catch popped 5267520,5267520,stack,
    decref 5267520
    
    EXPECTED RESULT:
    
    pre-main prep time: 23 ms
    Creating cleanup item
    Destroying cleanup item
    
    EXPECTED RESULT WITH EXCEPTION DEBUG:
    
    pre-main prep time: 24 ms
    Creating cleanup item
    Compiled code throwing an exception, 5267520,8,357
    can_catch on 5267520
    cxa_begin_catch 5267520,stack,5267520
    addref 5267520
    Compiled code RE-throwing an exception, popped 5267520,5267520,stack,
      5267520
    can_catch on 5267520
    cxa_end_catch popped 5267520,5267520,stack,
    decref 5267520
    cxa_begin_catch 5267520,stack,5267520
    addref 5267520
    cxa_end_catch popped 5267520,0,stack,
    decref 5267520
    Destroying cleanup item
    decref freeing exception 5267520,0,stack,
    
    =======================================================================
    
    Issue 2: Resuming exception unwinding causes crash when resumed
             exceptions have multiple references
    
    Repro:
    
     #include <iostream>
    
    struct NeedsCleanUp
    {
        const int item;
    
        NeedsCleanUp(int i)
            : item { i }
        {
            std::cout << "Creating cleanup item " << item << std::endl;
        }
    
        NeedsCleanUp(const NeedsCleanUp& src)
            : item { 100 + src.item }
        {
            std::cout << "Copying cleanup item " << src.item << " to "
                      << item << std::endl;
        }
    
        ~NeedsCleanUp()
        {
            std::cout << "Destroying cleanup item " << item << std::endl;
        }
    };
    
    int main(int argc, char* argv[])
    {
        NeedsCleanUp ex { 1 };
        std::exception_ptr exp1 { std::make_exception_ptr(ex) };
        std::exception_ptr exp2 { exp1 };
    
        try
        {
            [&exp1] {
                NeedsCleanUp cl { 2 };  // causes "resuming exception"
                                        // ref count reset
                std::rethrow_exception(exp1);
            } ();
        }
        catch (...)
        {
        }
    
        return 0;
    }
    
    Build and run:
    em++ -g -std=c++11 --emrun -s EXCEPTION_DEBUG=0 -o exc2.html exc2.cpp
    emrun --browser chrome exc2.html
    
    ACTUAL RESULT:
    
    pre-main prep time: 23 ms
    Creating cleanup item 1
    Copying cleanup item 1 to 101
    Copying cleanup item 101 to 201
    Destroying cleanup item 101
    Creating cleanup item 2
    Destroying cleanup item 2
    Destroying cleanup item 201
    exception thrown: TypeError: Cannot read property 'refcount' of
      undefined,TypeError: Cannot read property 'refcount' of undefined
        at Object.decRef (http://localhost:6931/exc2.js:1564:20)
        at ___cxa_decrement_exception_refcount
           (http://localhost:6931/exc2.js:1578:18)
        at __ZNSt13exception_ptrD2Ev (http://localhost:6931/exc2.js:23642:2)
        at _main (http://localhost:6931/exc2.js:5993:3)
        at Object.asm._main (http://localhost:6931/exc2.js:65981:19)
        at Object.callMain (http://localhost:6931/exc2.js:66150:30)
        at doRun (http://localhost:6931/exc2.js:66208:60)
        at http://localhost:6931/exc2.js:66219:7
    
    ACTUAL RESULT WITH EXCEPTION DEBUG:
    
    pre-main prep time: 22 ms
    Creating cleanup item 1
    Copying cleanup item 1 to 101
    Copying cleanup item 101 to 201
    Compiled code throwing an exception, 5267520,8,360
    can_catch on 5267520
    cxa_begin_catch 5267520,stack,5267520
    addref 5267520
    addref 5267520
    cxa_end_catch popped 5267520,5267520,stack,
    decref 5267520
    Destroying cleanup item 101
    addref 5267520
    Creating cleanup item 2
    addref 5267520
    Compiled code RE-throwing an exception, popped 5267520,0,stack,
    can_catch on 5267520
    decref 5267520
    Destroying cleanup item 2
    Resuming exception 5267520,5267520
    can_catch on 5267520
    cxa_begin_catch 5267520,stack,5267520
    addref 5267520
    decref 5267520
    Destroying cleanup item 201
    decref freeing exception 5267520,5267520,stack,5267520
    no de-adjustment for unknown exception ptr 5267520
    decref 5267520
    exception thrown: TypeError: Cannot read property 'refcount' of
      undefined,TypeError: Cannot read property 'refcount' of undefined
        at Object.decRef (http://localhost:6931/exc2.js:1568:20)
        at ___cxa_decrement_exception_refcount
           (http://localhost:6931/exc2.js:1583:18)
        at __ZNSt13exception_ptrD2Ev (http://localhost:6931/exc2.js:23654:2)
        at _main (http://localhost:6931/exc2.js:6005:3)
        at Object.asm._main (http://localhost:6931/exc2.js:65993:19)
        at Object.callMain (http://localhost:6931/exc2.js:66162:30)
        at doRun (http://localhost:6931/exc2.js:66220:60)
        at http://localhost:6931/exc2.js:66231:7
    
    EXPECTED RESULT:
    
    pre-main prep time: 22 ms
    Creating cleanup item 1
    Copying cleanup item 1 to 101
    Copying cleanup item 101 to 201
    Destroying cleanup item 101
    Creating cleanup item 2
    Destroying cleanup item 2
    Destroying cleanup item 201
    Destroying cleanup item 1
    
    EXPECTED RESULT WITH EXCEPTION DEBUG:
    
    pre-main prep time: 27 ms
    Creating cleanup item 1
    Copying cleanup item 1 to 101
    Copying cleanup item 101 to 201
    Compiled code throwing an exception, 5267520,8,360
    can_catch on 5267520
    cxa_begin_catch 5267520,stack,5267520
    addref 5267520
    addref 5267520
    cxa_end_catch popped 5267520,5267520,stack,
    decref 5267520
    Destroying cleanup item 101
    addref 5267520
    Creating cleanup item 2
    addref 5267520
    Compiled code RE-throwing an exception, popped 5267520,0,stack,5267520
    can_catch on 5267520
    decref 5267520
    Destroying cleanup item 2
    Resuming exception 5267520,5267520
    can_catch on 5267520
    cxa_begin_catch 5267520,stack,5267520,5267520
    addref 5267520
    cxa_end_catch popped 5267520,5267520,stack,5267520
    decref 5267520
    decref 5267520
    decref 5267520
    Destroying cleanup item 201
    decref freeing exception 5267520,0,stack,5267520
    Destroying cleanup item 1
    rbit committed Oct 8, 2016
    Configuration menu
    Copy the full SHA
    0b5bf76 View commit details
    Browse the repository at this point in the history
Loading