diff options
author | Richard Grenville <[email protected]> | 2014-01-21 22:13:06 +0800 |
---|---|---|
committer | Richard Grenville <[email protected]> | 2014-01-21 22:13:06 +0800 |
commit | 53cb5d3a46dfd13c1185f005674224b3c9ad0a3d (patch) | |
tree | 9d9fe02134109402aaf45a9077c4320d3d9022a7 | |
parent | b68985f96fd2b4737fd2168f27105b9b662fcc19 (diff) | |
download | tdebase-53cb5d3a46dfd13c1185f005674224b3c9ad0a3d.tar.gz tdebase-53cb5d3a46dfd13c1185f005674224b3c9ad0a3d.zip |
Bug fix: Fix access to freed memory due to invalid w->prev_trans
- Fix a bug that w->prev_trans sometimes points to freed memory.
Probably related to #165.
- Add some more debugging printf()-s under DEBUG_EVENTS.
-rw-r--r-- | compton.c | 29 |
1 files changed, 28 insertions, 1 deletions
@@ -1245,6 +1245,7 @@ paint_preprocess(session_t *ps, win *list) { t = w; } else { + assert(w->destroyed == (w->fade_callback == destroy_callback)); check_fade_fin(ps, w); } @@ -2089,6 +2090,10 @@ map_win(session_t *ps, Window id) { win *w = find_win(ps, id); +#ifdef DEBUG_EVENTS + printf_dbgf("(%#010lx \"%s\"): %p\n", id, (w ? w->name: NULL), w); +#endif + // Don't care about window mapping if it's an InputOnly window // Try avoiding mapping a window twice if (!w || InputOnly == w->a.class @@ -2824,6 +2829,10 @@ add_win(session_t *ps, Window id, Window prev) { // Allocate and initialize the new win structure win *new = malloc(sizeof(win)); +#ifdef DEBUG_EVENTS + printf_dbgf("(%#010lx): %p\n", id, new); +#endif + if (!new) { printf_errf("(%#010lx): Failed to allocate memory for the new window.", id); return false; @@ -3078,10 +3087,18 @@ circulate_win(session_t *ps, XCirculateEvent *ce) { static void finish_destroy_win(session_t *ps, Window id) { - win **prev, *w; + win **prev = NULL, *w = NULL; + +#ifdef DEBUG_EVENTS + printf_dbgf("(%#010lx): Starting...\n", id); +#endif for (prev = &ps->list; (w = *prev); prev = &w->next) { if (w->id == id && w->destroyed) { +#ifdef DEBUG_EVENTS + printf_dbgf("(%#010lx \"%s\"): %p\n", id, w->name, w); +#endif + finish_unmap_win(ps, w); *prev = w->next; @@ -3091,6 +3108,12 @@ finish_destroy_win(session_t *ps, Window id) { free_win_res(ps, w); + // Drop w from all prev_trans to avoid accessing freed memory in + // repair_win() + for (win *w2 = ps->list; w2; w2 = w2->next) + if (w == w2->prev_trans) + w2->prev_trans = NULL; + free(w); break; } @@ -3106,6 +3129,10 @@ static void destroy_win(session_t *ps, Window id) { win *w = find_win(ps, id); +#ifdef DEBUG_EVENTS + printf_dbgf("(%#010lx \"%s\"): %p\n", id, (w ? w->name: NULL), w); +#endif + if (w) { unmap_win(ps, w); |