[dev] [dwm] Question regarding `unmanage()` in while loop

From: Paul Menzel <pmenzel_AT_molgen.mpg.de>
Date: Wed, 3 Aug 2016 15:32:05 +0200

Dear suckless folks,


sorry, for being ignorant, but I have one question regarding the warning
below from Clang’s static analyzer scan-build.

```
dwm.c:480:4: warning: Use of memory after it is freed
                         unmanage(m->stack, 0);
                         ^~~~~~~~~~~~~~~~~~~~~
```

The code [1], looks like below.

```
[…]
void
detach(Client *c)
{
         Client **tc;

         for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next);
         *tc = c->next;
}

void
detachstack(Client *c)
{
         Client **tc, *t;

         for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext);
         *tc = c->snext;

         if (c == c->mon->sel) {
                 for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext);
                 c->mon->sel = t;
         }
}
[…]
void
unmanage(Client *c, int destroyed)
{
         Monitor *m = c->mon;
         XWindowChanges wc;

         /* The server grab construct avoids race conditions. */
         detach(c);
         detachstack(c);
         if (!destroyed) {
                 wc.border_width = c->oldbw;
                 XGrabServer(dpy);
                 XSetErrorHandler(xerrordummy);
                 XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /*
restore border */
                 XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
                 setclientstate(c, WithdrawnState);
                 XSync(dpy, False);
                 XSetErrorHandler(xerror);
                 XUngrabServer(dpy);
         }
         free(c);
         focus(NULL);
         updateclientlist();
         arrange(m);
}
[…]
void
cleanup(void)
{
         Arg a = {.ui = ~0};
         Layout foo = { "", NULL };
         Monitor *m;
         size_t i;

         view(&a);
         selmon->lt[selmon->sellt] = &foo;
         for (m = mons; m; m = m->next)
                 if (m->stack)
                         unmanage(m->stack, 0);
         XUngrabKey(dpy, AnyKey, AnyModifier, root);
         while (mons)
                 cleanupmon(mons);
         for (i = 0; i < CurLast; i++)
                 drw_cur_free(drw, cursor[i]);
         for (i = 0; i < SchemeLast; i++)
                 free(scheme[i]);
         drw_free(drw);
         XSync(dpy, False);
         XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
         XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
}
[…]
```

Unfortunately, my C knowledge is not good enough to understand, why the
while loop is used here. Even reading the called functions, I don’t see
why `m->stack`, a pointer, should be checked in the while condition. Is
it set to `NULL` somewhere?


Thank you in advance.


Best regards,

Paul


[1] http://git.suckless.org/dwm/tree/dwm.c#n480
Received on Wed Aug 03 2016 - 15:32:05 CEST

This archive was generated by hypermail 2.3.0 : Wed Aug 03 2016 - 15:36:13 CEST