[Xcb] [PATCH 1/2] xcb_disconnect(): Fix leak with error connections

Uli Schlachter psychon at znc.in
Tue Dec 31 06:57:16 PST 2013


There are two kind of error connections in XCB. First, if something goes wrong
while the connection is being set up, _xcb_conn_ret_error() is used to return a
static connection in an error state. If something goes wrong later,
_xcb_conn_shutdown() is used to set c->has_error.

This is important, because the static object that _xcb_conn_ret_error() returns
must not be freed, while the dynamically allocated objects that go through
_xcb_conn_shutdown() must obviously be properly deallocated.

This used to work correctly, but in 769acff0da8, xcb_disconnect() was made to
ignore all connections in an error state completely. Fix this by only ignoring
the few static error connections that we have.

This was tested with the following hack:

    xcb_connection_t *c = xcb_connect(NULL, NULL);
    close(xcb_get_file_descriptor(c));
    xcb_discard_reply(c, xcb_get_input_focus(c).sequence);
    xcb_flush(c);
    xcb_disconnect(c);

Valgrind confirms that xcb has a memory leak before this patch that this patch
indeed fixes.

Signed-off-by: Uli Schlachter <psychon at znc.in>
---
 src/xcb_conn.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/xcb_conn.c b/src/xcb_conn.c
index 46390e1..9da11b0 100644
--- a/src/xcb_conn.c
+++ b/src/xcb_conn.c
@@ -64,6 +64,7 @@ typedef struct {
     uint16_t length;
 } xcb_setup_generic_t;
 
+/* Keep this list in sync with xcb_disconnect()! */
 static const int xcb_con_error = XCB_CONN_ERROR;
 static const int xcb_con_closed_mem_er = XCB_CONN_CLOSED_MEM_INSUFFICIENT;
 static const int xcb_con_closed_parse_er = XCB_CONN_CLOSED_PARSE_ERR;
@@ -341,7 +342,10 @@ xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info)
 
 void xcb_disconnect(xcb_connection_t *c)
 {
-    if(c->has_error)
+    if(c == (xcb_connection_t *) &xcb_con_error ||
+            c == (xcb_connection_t *) &xcb_con_closed_mem_er ||
+            c == (xcb_connection_t *) &xcb_con_closed_parse_er ||
+            c == (xcb_connection_t *) &xcb_con_closed_screen_er)
         return;
 
     free(c->setup);
-- 
1.8.5.2



More information about the Xcb mailing list