1
0
mirror of https://github.com/weechat/weechat.git synced 2026-07-04 16:53:14 +02:00

core: fix random crash when closing a buffer

The problem happened because we used a pointer to a
"struct t_gui_buffer_visited" for the switch to another buffer,
when the buffer is closed. This is executed in all windows displaying
the buffer, but on each switch to buffer, the visited buffers are
updated and therefore the address can change. The pointer becomes
invalid, and WeeChat still uses it on next windows for the buffer
switch.

It happened rarely because the visited buffer is freed and allocated
immediately after, so the address is often the same in memory.

Thanks to silverd for the tests on OS X to track the problem.
This commit is contained in:
Sebastien Helleu
2013-12-01 08:37:22 +01:00
parent 983791de84
commit 9a160509d7
2 changed files with 10 additions and 5 deletions
+1
View File
@@ -11,6 +11,7 @@ http://weechat.org/files/releasenotes/ReleaseNotes-devel.html[release notes]
== Version 0.4.3 (under dev)
* core: fix random crash when closing a buffer
* core: fix crash on /buffer close core.weechat
* core: add option "libs" for command /debug
* core: apply color attributes when clearing a window (patch #8236)
+9 -5
View File
@@ -2126,6 +2126,7 @@ gui_buffer_close (struct t_gui_buffer *buffer)
{
struct t_gui_window *ptr_window;
struct t_gui_buffer *ptr_buffer, *ptr_back_to_buffer;
struct t_gui_buffer *ptr_buffer_visited_buffer;
int index;
struct t_gui_buffer_visited *ptr_buffer_visited;
@@ -2152,7 +2153,7 @@ gui_buffer_close (struct t_gui_buffer *buffer)
* find other buffer to display: previously visited buffer if current
* window is displaying buffer, or buffer # - 1
*/
ptr_buffer_visited = NULL;
ptr_buffer_visited_buffer = NULL;
if (CONFIG_BOOLEAN(config_look_jump_previous_buffer_when_closing)
&& gui_current_window && (gui_current_window->buffer == buffer))
{
@@ -2160,8 +2161,11 @@ gui_buffer_close (struct t_gui_buffer *buffer)
if (index >= 0)
{
ptr_buffer_visited = gui_buffer_visited_search_by_number (index);
if (ptr_buffer_visited->buffer == buffer)
ptr_buffer_visited = NULL;
if (ptr_buffer_visited
&& (ptr_buffer_visited->buffer != buffer))
{
ptr_buffer_visited_buffer = ptr_buffer_visited->buffer;
}
}
}
@@ -2181,10 +2185,10 @@ gui_buffer_close (struct t_gui_buffer *buffer)
ptr_back_to_buffer,
1);
}
else if (ptr_buffer_visited)
else if (ptr_buffer_visited_buffer)
{
gui_window_switch_to_buffer (ptr_window,
ptr_buffer_visited->buffer,
ptr_buffer_visited_buffer,
1);
}
else if (ptr_window->buffer->prev_buffer)