[Libwebsockets] Suspected memory leak issue while connecting to an unconnectable server

Andy Green andy at warmcat.com
Fri Feb 26 11:12:12 CET 2021

On 2/26/21 2:10 AM, Rick Li wrote:
> Hi,
> I had a suspected memory leak issue while connecting to an unconnectable 
> WebSocket server on v3.2-statble. The scenario is when connected to an 
> unconnectable WebSocket server(always return HTTP/1.1 301 Moved 
> Permanently) it will receive "Error: closed before established" on 
> console output, then I will use those two APIs to cancel and destroy the 
> context of wsi.
> lws_cancel_service(m_pCtx);

Not sure if you already understand it but "cancel" here just means to 
force the an event, it's "cancelling the wait", it's not changing the 
lifecycle state of the loop.

You might need to do that to get your close action to happen if the lws 
thread is idle and waiting for an event and the decision to destroy it 
originally came from a different thread.  But it's not itself a 
necessary step itself before the destroy, the name is a bit misleading.

> lws_context_destroy(m_pCtx);
> In my test scenario it will loop for 10000 times then the memory usage 
> will increase about 2M bytes, I tried to use  UMDH to dump the leak 
> statement and the log as below.
> + 2826500 ( 2826500 -      0)   5653 allocs BackTrace3DD8748
> +    5653 (   5653 -      0) BackTrace3DD8748 allocations
> ntdll!RtlWalkHeap+194
> ntdll!RtlCaptureStackContext+EC8F
> ntdll!RtlAllocateHeap+3E
> ucrtbased!calloc_base+D75
> ucrtbased!calloc_base+B96
> ucrtbased!malloc_dbg+1A
> ucrtbased!calloc_base+1295
> ucrtbased!realloc_dbg+6B
> ucrtbased!realloc+18
> websockets!_realloc+50 
> (G:\websocket\Websocket\Websocket\libwebsockets\lib\core\alloc.c, 109)
> websockets!lws_zalloc+30 

Windows doesn't actually have pipe() to create the event pipes, he's 
using a windows event on 3.2.

How about this?

diff --git a/lib/core/context.c b/lib/core/context.c
index 5d2aa33d..0023d39a 100644
--- a/lib/core/context.c
+++ b/lib/core/context.c
@@ -637,6 +637,15 @@ lws_context_destroy3(struct lws_context *context)

+#if defined(WIN32)
+	for (n = 0; n < context->count_threads; n++) {
+		if (!context->pt[n].pipe_wsi)
+			continue;
+		lws_free_set_NULL(context->pt[n].pipe_wsi);
+	}
  	lwsl_info("%s: ctx %p freed\n", __func__, context);

FYI the windows support is significantly improved on main branch (soon 
to become v4.2).


More information about the Libwebsockets mailing list