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

Fix memory leak. Not all tasks are deleted in thread_d dtor. #130

Merged
merged 1 commit into from
May 21, 2019

Conversation

OpenLedgerApp
Copy link

In thread::quit()
{
...
my->start_next_fiber(true)
...
}
my->start_next_fiber(true) - an exception is raised from here and a context has yet a pointer to the task that will never released and memory will not freed.
So to avoid such situation in ~thread_d() lets release it.
to reproduce run: --tool=memcheck --leak-check=full ./all_tests -t thread_tests

current->cur_task = 0;
next->_set_active_context(0);
next->release();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean before the change, next never got freed? Would this PR fix bitshares/bitshares-core#1006?

Copy link
Author

@OpenLedgerApp OpenLedgerApp May 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean before the change, next never got freed?

Yes, in the case if thread::quit() was called the task "async thread::quit()" will be newer freed. I've added "fc::shared_ptr<task_base> next_ptr(next)" in this place just for so as not to explicitly call the "next->release();".

In the case "thread::quit()" an exception is raised from "my->start_next_fiber(true)" and everything will not called that is after (see run_next_task() {... next->run(); ... don't get here }.
In the ~thread_d I check if ready_context has a task and free the last.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bitshares/bitshares-core#1006?

Right now I have no answer. Necessary make additional research.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean before the change, next never got freed?

The call to next->release() will delete *next if this was the last reference to it. (retainable and its retain/release methods implement reference counting, used by task_base and fc::shared_ptr. It's a mess, don't ask. I'm working on eliminating this at least partially in bitshares/bitshares-core#1584 .)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think next->run() will ever throw, so why change this here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a mess, don't ask.

Yes, you are right absolutely. )

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think next->run() will ever throw, so why change this here?

Yes, this change is not necessary, as I wrote before, just for so as not to explicitly call release.

@pmconrad
Copy link

The memory leak is probably negligible in practice, because we don't create/destroy threads during normal operation. Only on startup/shutdown.

Of course it should still be fixed. Thanks for your investigation!

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

Successfully merging this pull request may close these issues.

4 participants