From 507d9b5f9ed14ea5b6091aebdcc20dfd234726ab Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Sat, 11 Nov 2017 13:01:47 -0600 Subject: core: Add cache_media_frames debugging option. The media frame cache gets in the way of finding use after free errors of media frames. Tools like valgrind and MALLOC_DEBUG don't know when a frame is released because it gets put into the cache instead of being freed. * Added the "cache_media_frames" option to asterisk.conf. Disabling the option helps track down media frame mismanagement when using valgrind or MALLOC_DEBUG. The cache gets in the way of determining if the frame is used after free and who freed it. NOTE: This option has no effect when Asterisk is compiled with the LOW_MEMORY compile time option enabled because the cache code does not exist. To disable the media frame cache simply disable the cache_media_frames option in asterisk.conf and restart Asterisk. Sample asterisk.conf setting: [options] cache_media_frames=no ASTERISK-27413 Change-Id: I0ab2ce0f4547cccf2eb214901835c2d951b78c00 --- main/frame.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'main/frame.c') diff --git a/main/frame.c b/main/frame.c index 4261b04dd..db2b96743 100644 --- a/main/frame.c +++ b/main/frame.c @@ -122,14 +122,18 @@ static void __frame_free(struct ast_frame *fr, int cache) return; #if !defined(LOW_MEMORY) - if (cache && fr->mallocd == AST_MALLOCD_HDR) { + if (fr->mallocd == AST_MALLOCD_HDR + && cache + && ast_opt_cache_media_frames) { /* Cool, only the header is malloc'd, let's just cache those for now * to keep things simple... */ struct ast_frame_cache *frames; - if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames))) && - (frames->size < FRAME_CACHE_MAX_SIZE)) { - if ((fr->frametype == AST_FRAME_VOICE) || (fr->frametype == AST_FRAME_VIDEO) || - (fr->frametype == AST_FRAME_IMAGE)) { + + frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)); + if (frames && frames->size < FRAME_CACHE_MAX_SIZE) { + if (fr->frametype == AST_FRAME_VOICE + || fr->frametype == AST_FRAME_VIDEO + || fr->frametype == AST_FRAME_IMAGE) { ao2_cleanup(fr->subclass.format); } @@ -149,8 +153,9 @@ static void __frame_free(struct ast_frame *fr, int cache) ast_free((void *) fr->src); } if (fr->mallocd & AST_MALLOCD_HDR) { - if ((fr->frametype == AST_FRAME_VOICE) || (fr->frametype == AST_FRAME_VIDEO) || - (fr->frametype == AST_FRAME_IMAGE)) { + if (fr->frametype == AST_FRAME_VOICE + || fr->frametype == AST_FRAME_VIDEO + || fr->frametype == AST_FRAME_IMAGE) { ao2_cleanup(fr->subclass.format); } -- cgit v1.2.3