summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2017-11-11 13:01:47 -0600
committerRichard Mudgett <rmudgett@digium.com>2017-11-11 13:45:02 -0600
commitcb63ade61128834d9eb14bffc993174057a966d3 (patch)
tree7f143dd69a6966db2d80cab8fcd40a062460cf3a /main
parent6c84a1edd9e2b80269ede1ea9da159adad868afa (diff)
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
Diffstat (limited to 'main')
-rw-r--r--main/asterisk.c8
-rw-r--r--main/frame.c19
2 files changed, 20 insertions, 7 deletions
diff --git a/main/asterisk.c b/main/asterisk.c
index 40986a484..20ed947f7 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -607,6 +607,9 @@ static char *handle_show_settings(struct ast_cli_entry *e, int cmd, struct ast_c
ast_cli(a->fd, " Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE) ? "Enabled" : "Disabled");
ast_cli(a->fd, " Generic PLC: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC) ? "Enabled" : "Disabled");
ast_cli(a->fd, " Min DTMF duration:: %u\n", option_dtmfminduration);
+#if !defined(LOW_MEMORY)
+ ast_cli(a->fd, " Cache media frames: %s\n", ast_opt_cache_media_frames ? "Enabled" : "Disabled");
+#endif
ast_cli(a->fd, " RTP use dynamic payloads: %u\n", ast_option_rtpusedynamic);
if (ast_option_rtpptdynamic == AST_RTP_PT_LAST_REASSIGN) {
@@ -3714,6 +3717,11 @@ static void ast_readconfig(void)
/* Cache recorded sound files to another directory during recording */
} else if (!strcasecmp(v->name, "cache_record_files")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES);
+#if !defined(LOW_MEMORY)
+ /* Cache media frames for performance */
+ } else if (!strcasecmp(v->name, "cache_media_frames")) {
+ ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_MEDIA_FRAMES);
+#endif
/* Specify cache directory */
} else if (!strcasecmp(v->name, "record_cache_dir")) {
ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN);
diff --git a/main/frame.c b/main/frame.c
index c24cc8f78..690d48e27 100644
--- a/main/frame.c
+++ b/main/frame.c
@@ -120,14 +120,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);
}
@@ -147,8 +151,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);
}