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 windows SockState reference counting + misc clean-ups #1149

Closed
wants to merge 4 commits into from

Conversation

piscisaureus
Copy link
Contributor

No description provided.

@piscisaureus
Copy link
Contributor Author

@dtacalau Can you check this PR for the memory leak you discovered?

@piscisaureus piscisaureus changed the title Fix IO_STATUS_BLOCK/AFD_POLL_INFO reference counting Fix windows SockState reference counting + misc clean-ups Nov 14, 2019
@dtacalau
Copy link
Contributor

@dtacalau Can you check this PR for the memory leak you discovered?

Sure, will check it!

@dtacalau
Copy link
Contributor

dtacalau commented Nov 14, 2019

@piscisaureus I've checked this PR on all tests, here are the results:

  1. For test from issue Windows mio leaks memory when poll does not retrieve any event #1146, it still reproducing:
~~Dr.M~~ Error #5: LEAK 128 direct bytes 0x0000008d40fffb00-0x0000008d40fffb80 + 40 indirect bytes
~~Dr.M~~ # 0 replace_RtlAllocateHeap                                                    [d:\drmemory_package\common\alloc_replace.c:3771]
~~Dr.M~~ # 1 alloc::alloc::alloc                                                        [/rustc/625451e376bb2e5283fc4741caa0a3e8a2ca4d54\src\liballoc\alloc.rs:84]
~~Dr.M~~ # 2 alloc::alloc::exchange_malloc                                              [/rustc/625451e376bb2e5283fc4741caa0a3e8a2ca4d54\src\liballoc\alloc.rs:206]
~~Dr.M~~ # 3 alloc::sync::Arc<>::new<>                                                  [/rustc/625451e376bb2e5283fc4741caa0a3e8a2ca4d54\src\liballoc\sync.rs:306]
~~Dr.M~~ # 4 alloc::sync::Arc<>::pin<>                                                  [/rustc/625451e376bb2e5283fc4741caa0a3e8a2ca4d54\src\liballoc\sync.rs:318]
~~Dr.M~~ # 5 mio::sys::windows::selector::SelectorInner::_alloc_sock_for_rawsocket      [C:\work\git\mio\src\sys\windows\selector.rs:608]
~~Dr.M~~ # 6 mio::sys::windows::selector::SelectorInner::register<>                     [C:\work\git\mio\src\sys\windows\selector.rs:466]
~~Dr.M~~ # 7 mio::sys::windows::selector::Selector::register<>                          [C:\work\git\mio\src\sys\windows\selector.rs:333]
~~Dr.M~~ # 8 mio::sys::windows::tcp::{{impl}}::register                                 [C:\work\git\mio\src\sys\windows\tcp.rs:453]
~~Dr.M~~ # 9 mio::net::tcp::listener::{{impl}}::register                                [C:\work\git\mio\src\net\tcp\listener.rs:142]
~~Dr.M~~ #10 core::sync::atomic::AtomicUsize::load                                      [/rustc/625451e376bb2e5283fc4741caa0a3e8a2ca4d54\src\libcore\sync\atomic.rs:1296]
~~Dr.M~~ #11 mio::poll::Registry::register<>                                            [C:\work\git\mio\src\poll.rs:494]
~~Dr.M~~
~~Dr.M~~ ERRORS FOUND:
~~Dr.M~~       0 unique,     0 total unaddressable access(es)
~~Dr.M~~       4 unique,     4 total uninitialized access(es)
~~Dr.M~~       0 unique,     0 total invalid heap argument(s)
~~Dr.M~~       0 unique,     0 total GDI usage error(s)
~~Dr.M~~       0 unique,     0 total handle leak(s)
~~Dr.M~~       0 unique,     0 total warning(s)
~~Dr.M~~       1 unique,     1 total,    168 byte(s) of leak(s)
~~Dr.M~~       0 unique,     0 total,      0 byte(s) of possible leak(s)
~
  1. Tests from registering.rs also leak, Multiple mio tests leak memory on Windows #1150
running 5 tests
test udp_register_multiple_event_loops ... ok
test tcp_register_multiple_event_loops ... ok
test registering_after_deregistering ... ok
test register_deregister ... ok
test reregister_different_without_poll ... ok

test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
~~Dr.M~~ Error #5: LEAK 128 direct bytes 0x032c14e0-0x032c1560 + 0 indirect bytes
~~Dr.M~~ Error #6: POSSIBLE LEAK 200 direct bytes 0x032c9820-0x032c98e8 + 26 indirect bytes
~~Dr.M~~ Error #7: POSSIBLE LEAK 60 direct bytes 0x032c9908-0x032c9944 + 0 indirect bytes
~~Dr.M~~ ERRORS FOUND:
~~Dr.M~~       1 unique,     1 total,    128 byte(s) of leak(s)
~~Dr.M~~       2 unique,     2 total,    286 byte(s) of possible leak(s)

self.pending_evts = self.user_evts;
forget(self_arc.clone());
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks strange, why call forget on the clone and not on the self_arc directly?

Copy link
Contributor Author

@piscisaureus piscisaureus Nov 14, 2019

Choose a reason for hiding this comment

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

self_arc is a reference here. Dropping a reference does is no-op, therefore ’forget’ing a reference instead of dropping doesn't make any difference.

@@ -626,7 +585,7 @@ impl SelectorInner {
n += 1;
continue;
}
let sock_arc = Arc::from_raw(iocp_event.overlapped() as *const Mutex<SockState>);
let sock_arc: Pin<Arc<Mutex<SockState>>> = transmute_copy(&iocp_event.overlapped());
Copy link
Contributor

Choose a reason for hiding this comment

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

is this a perfect copy without increasing the ref count?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep. It's basically reinterpret_cast + copy.

@dtacalau
Copy link
Contributor

0001-Added-support-to-cancel-sock-state-on-selector-drop.zip

@piscisaureus here's a patch done on your branch which add support for cancel on drop. Using this patch there are no more leaks. Let me know what you think!

piscisaureus and others added 2 commits November 14, 2019 10:51
…nt memory leaks for sockets which have been registered and haven't been deregistered or sockets with no events polled.

Signed-off-by: Daniel Tacalau <dst4096@gmail.com>
@piscisaureus
Copy link
Contributor Author

@dtacalau

I've addressed the correctness issues I found in your patch (it's still messy nonetheless) and added a counter to check for leaked SockState (now SockStateInner) objects. Based on the counter I'd say that there are no SockStateInner objects being leaked. However DrMemory still finds leaks for me, so I'm pretty sure it's something else that's leaking.

@piscisaureus
Copy link
Contributor Author

@dtacalau I would actually suggest to land b994c29 first. It may not fix the leak but it does clean up a bunch of other stuff.

@dtacalau
Copy link
Contributor

@dtacalau I would actually suggest to land b994c29 first. It may not fix the leak but it does clean up a bunch of other stuff.

@piscisaureus not sure about merging b994c29. It looks like a lot of refactoring done and release date is getting close, test coverage could be better, feels risky. I'd defer this decision to @carllerche and @Thomasdezeeuw.

But if we still want to merge this, I'd suggest splitting it in multiple, more trackable, smaller commits, i.e: one comit for fix windows Sock ref count, multiple misc clean-ups comits.

@dtacalau
Copy link
Contributor

dtacalau commented Nov 15, 2019

@piscisaureus Have a look at #1147, I've redone my initial mem leak fix by just adding the cancel sockstate on drop on current master and all the leaks are gone. Not sure if the correctness issues you've mentioned are gone, can you take a look? We could merge this to keep things simple.

@piscisaureus
Copy link
Contributor Author

piscisaureus commented Nov 16, 2019

@dtacalau

@piscisaureus not sure about merging b994c29. It looks like a lot of refactoring done and release date is getting close, test coverage could be better, feels risky. I'd defer this decision to @carllerche and @Thomasdezeeuw.

But if we still want to merge this, I'd suggest splitting it in multiple, more trackable, smaller commits, i.e: one comit for fix windows Sock ref count, multiple misc clean-ups comits.

Fair enough. WDYT about #1154? That at least gets rid of an unnecessary Box around Overlapped and that wonky self_overlapped thing.

@Thomasdezeeuw
Copy link
Collaborator

Is the plan to merge #1154 first? Because I think there is some overlap/conflicts with this pr.

@dtacalau
Copy link
Contributor

Fair enough. WDYT about #1154? That at least gets rid of an unnecessary Box around Overlapped and that wonky self_overlapped thing.

@piscisaureus #1154 looks good! We still need to fix the mem leak afterwards.

@dtacalau
Copy link
Contributor

Is the plan to merge #1154 first? Because I think there is some overlap/conflicts with this pr.

@Thomasdezeeuw Here's how I see the plan: I also think #1154 should be merged first. The misc clean-ups done by @piscisaureus are definitely useful, but, to me, it seemed too many changes at once, so I suggested splitting them in multiple commits.

At the same time we should come up with a fix for the memory leaks (delete remaining sock states when doing selector drop).

@Thomasdezeeuw
Copy link
Collaborator

#1154 is merged, what is left to do here?

@dtacalau
Copy link
Contributor

#1154 is merged, what is left to do here?

@Thomasdezeeuw there are several misc clean-ups remaining. @piscisaureus do you want to create a separate commit with remaining clean-ups so we can merge them?

@piscisaureus
Copy link
Contributor Author

@Thomasdezeeuw there are several misc clean-ups remaining. @piscisaureus do you want to create a separate commit with remaining clean-ups so we can merge them?

I'll do it when I have time, but I won't have time for at least a week and a half.

These misc cleanups are not super important IMO, so just forget about them for now. There were a few small bug fixes contained in the patch. When I have the time I'll prioritize on landing those.

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.

3 participants