Fix leak of struct call_thread_fsm in call_function_by_hand_dummy.

When the call does not complete, the call_thread_fsm allocated
by new_call_thread_fsm is not cleaned up and deleted, which causes
the following leak e.g. in gdb.base/callfuncs.exp:

==29263== 560 bytes in 7 blocks are definitely lost in loss record 2,833 of 3,341
==29263==    at 0x4C2E0BC: calloc (vg_replace_malloc.c:762)
==29263==    by 0x405110: xcalloc (common-utils.c:84)
==29263==    by 0x4E67EB: xcnew<call_thread_fsm> (poison.h:122)
==29263==    by 0x4E67EB: new_call_thread_fsm (infcall.c:516)
==29263==    by 0x4E67EB: call_function_by_hand_dummy(value*, type*, gdb::array_view<value*>, void (*)(void*, int), void*) (infcall.c:1154)
==29263==    by 0x4E784E: call_function_by_hand(value*, type*, gdb::array_view<value*>) (infcall.c:693)
==29263==    by 0x496111: eval_call(expression*, noside, int, value**, char const*, type*) [clone .isra.5] (eval.c:835)

Fix the leak by similarly doing cleanup/destroy when restoring
previous state machine.

Tested on debian/amd64, natively and under valgrind.

2019-01-02  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	* infcall.c (call_function_by_hand_dummy): cleanup/destroy sm
	 in case of call that did not complete.
This commit is contained in:
Philippe Waroquiers 2019-01-01 20:54:52 +01:00
parent 5d36dfb949
commit e331924073
2 changed files with 9 additions and 2 deletions

View File

@ -1,3 +1,8 @@
2019-01-02 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* infcall.c (call_function_by_hand_dummy): cleanup/destroy sm
in case of call that did not complete.
2019-01-02 Andrey Utkin <autkin@undo.io>
* symfile.c (find_separate_debug_file): Fix search of debug files for

View File

@ -1189,8 +1189,10 @@ call_function_by_hand_dummy (struct value *function,
return retval;
}
/* Didn't complete. Restore previous state machine, and
handle the error. */
/* Didn't complete. Clean up / destroy the call FSM, and restore the
previous state machine, and handle the error. */
thread_fsm_clean_up (call_thread->thread_fsm, call_thread.get ());
thread_fsm_delete (call_thread->thread_fsm);
call_thread->thread_fsm = saved_sm;
}
}