Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when using process #87

Closed
raoulh opened this issue Mar 24, 2017 · 5 comments
Closed

Crash when using process #87

raoulh opened this issue Mar 24, 2017 · 5 comments

Comments

@raoulh
Copy link
Contributor

raoulh commented Mar 24, 2017

Hi,

Using that example code:

#include <iostream>
#include "uvw.hpp"

class Object
{
public:
    Object()
    {
        std::cout << "Object()" << std::endl;
        proc = uvw::Loop::getDefault()->resource<uvw::ProcessHandle>();
        proc->once<uvw::ExitEvent>([](const uvw::ExitEvent &, auto &h)
        {
            std::cout << "process exited" << std::endl;
            h.close();
        });

        char *args[3];
        args[0] = "sleep";
        args[1] = "1";
        args[2] = NULL;

        proc->spawn(args[0], args);
    }
    ~Object()
    {
        std::cout << "~Object()" << std::endl;
        if (proc->referenced())
        {
            proc->kill(SIGTERM);
            proc->close();
            //Crash without this:
            // proc->once<uvw::CloseEvent>([h = proc](const uvw::CloseEvent &, auto &) { });
        }
    }

private:
    std::shared_ptr<uvw::ProcessHandle> proc;
};

int main(int argc, char **argv)
{
    auto loop = uvw::Loop::getDefault();

    Object *o = new Object();

    auto timer = loop->resource<uvw::TimerHandle>();
    timer->once<uvw::TimerEvent>([o](const auto &, auto &h)
    {
        delete o;
        h.close();
    });

    int time = atoi(argv[1]);
    timer->start(uvw::TimerHandle::Time{time},
                 uvw::TimerHandle::Time{time});

    loop->run();

    return 0;
}

This simple example crashes when the Object is deleted and the process is still running. For example if you start it with:

➜  src git:(upstream_master) ./test 200
Object()
~Object()
*** Error in `./test': double free or corruption (fasttop): 0x00000000014562e0 ***
======= Backtrace: =========
/usr/lib/libc.so.6(+0x722ab)[0x7f082ddd62ab]
/usr/lib/libc.so.6(+0x7890e)[0x7f082dddc90e]
/usr/lib/libc.so.6(+0x7911e)[0x7f082dddd11e]
./test[0x40f5b0]
./test[0x40d72a]
./test[0x40aa3c]
./test[0x40a19a]
./test[0x40708d]
./test[0x40c53b]
./test[0x408e82]
./test[0x40601d]
/usr/lib/libuv.so.1(uv_run+0x1d8)[0x7f082f2093a8]
./test[0x404b0d]
./test[0x401ca1]
/usr/lib/libc.so.6(__libc_start_main+0xf1)[0x7f082dd84511]
./test[0x40194a]

Deleting the object after it has finished works:

➜  src git:(upstream_master) ./test 2000
Object()
process exited
~Object()

It appears to crash in uvw::Handle::closeCallback when trying to get the uvw::Handle but it was already deleted when freeing Object. A workaround is to keep a reference of the uvw::Handle in a CloseEvent lambda like:

proc->once<uvw::CloseEvent>([h = proc](const uvw::CloseEvent &, auto &) { });

It works but it's not nice. Also this problem only occurs when using uvw::ProcessHandle.

@skypjack
Copy link
Owner

Good catch. I found the error. Let me fix it. I'll ping you as soon as possible.

@skypjack
Copy link
Owner

Fixed upstream. Thank you very much.

@raoulh
Copy link
Contributor Author

raoulh commented Mar 24, 2017

Nice :)

raoulh added a commit to calaos/calaos_base that referenced this issue Mar 24, 2017
@skypjack
Copy link
Owner

I saw you still capture a reference to the handle with a callback on the CloseEvent in your code. I forgot to mention that you don't need to do that anymore with the fix above mentioned. The handle should keep itself alive till the CloseEvent as expected. Let me know if you encounter other problems. Thank you.

@raoulh
Copy link
Contributor Author

raoulh commented Mar 24, 2017

Yes, I already pushed a fix with your fix, thanks a lot!
Extremely fast as always :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants