Index: include/asterisk/channel.h
===================================================================
--- include/asterisk/channel.h	(revision 422438)
+++ include/asterisk/channel.h	(working copy)
@@ -962,6 +962,10 @@
 	 * The data on chan->timingdata is an astobj2 object.
 	 */
 	AST_FLAG_TIMINGDATA_IS_AO2_OBJ = (1 << 26),
+	/*!
+	 * The channel is executing a subroutine or macro
+	 */
+	AST_FLAG_SUBROUTINE_EXEC = (1 << 27),
 };
 
 /*! \brief ast_bridge_config flags */
Index: apps/app_stack.c
===================================================================
--- apps/app_stack.c	(revision 422438)
+++ apps/app_stack.c	(working copy)
@@ -251,6 +251,8 @@
 	int priority;
 	/*! TRUE if the return location marks the end of a special routine. */
 	unsigned int is_special:1;
+	/*! Whether or not we were in a subroutine when this one was created */
+	int in_subroutine;
 	char *context;
 	char extension[0];
 };
@@ -310,7 +312,7 @@
 	ast_free(frame);
 }
 
-static struct gosub_stack_frame *gosub_allocate_frame(const char *context, const char *extension, int priority, unsigned char arguments)
+static struct gosub_stack_frame *gosub_allocate_frame(const char *context, const char *extension, int priority, int in_subroutine, unsigned char arguments)
 {
 	struct gosub_stack_frame *new = NULL;
 	int len_extension = strlen(extension), len_context = strlen(context);
@@ -321,6 +323,7 @@
 		new->context = new->extension + len_extension + 1;
 		strcpy(new->context, context);
 		new->priority = priority;
+		new->in_subroutine = in_subroutine;
 		new->arguments = arguments;
 	}
 	return new;
@@ -416,6 +419,7 @@
 		--oldframe->priority;
 	}
 	ast_channel_priority_set(chan, oldframe->priority);
+	ast_set2_flag(ast_channel_flags(chan), oldframe->in_subroutine, AST_FLAG_SUBROUTINE_EXEC);
 
 	gosub_release_frame(chan, oldframe);
 
@@ -524,6 +528,7 @@
 	char *orig_exten;
 	char *dest_context;
 	char *dest_exten;
+	int orig_in_subroutine;
 	int orig_priority;
 	int dest_priority;
 	int i;
@@ -563,6 +568,7 @@
 	orig_context = ast_strdupa(ast_channel_context(chan));
 	orig_exten = ast_strdupa(ast_channel_exten(chan));
 	orig_priority = ast_channel_priority(chan);
+	orig_in_subroutine = ast_test_flag(ast_channel_flags(chan), AST_FLAG_SUBROUTINE_EXEC);
 	ast_channel_unlock(chan);
 
 	if (ast_parseable_goto(chan, label)) {
@@ -630,7 +636,7 @@
 	}
 
 	/* Create the return address */
-	newframe = gosub_allocate_frame(orig_context, orig_exten, orig_priority + 1, max_argc);
+	newframe = gosub_allocate_frame(orig_context, orig_exten, orig_priority + 1, orig_in_subroutine, max_argc);
 	if (!newframe) {
 		goto error_exit_locked;
 	}
@@ -644,6 +650,8 @@
 	snprintf(argname, sizeof(argname), "%u", args2.argc);
 	frame_set_var(chan, newframe, "ARGC", argname);
 
+	ast_set_flag(ast_channel_flags(chan), AST_FLAG_SUBROUTINE_EXEC);
+
 	/* And finally, save our return address */
 	AST_LIST_LOCK(oldlist);
 	AST_LIST_INSERT_HEAD(oldlist, newframe, entries);
@@ -967,6 +975,7 @@
 	int saved_priority;
 	int saved_hangup_flags;
 	int saved_autoloopflag;
+	int saved_in_subroutine;
 	int res;
 
 	ast_channel_lock(chan);
@@ -990,6 +999,9 @@
 	saved_exten = ast_strdupa(ast_channel_exten(chan));
 	saved_priority = ast_channel_priority(chan);
 
+	/* Save whether or not we are in a subroutine */
+	saved_in_subroutine = ast_test_flag(ast_channel_flags(chan), AST_FLAG_SUBROUTINE_EXEC);
+
 	ast_debug(4, "%s Original location: %s,%s,%d\n", ast_channel_name(chan),
 		saved_context, saved_exten, saved_priority);
 
@@ -1091,6 +1103,9 @@
 	/* Restore autoloop flag */
 	ast_set2_flag(ast_channel_flags(chan), saved_autoloopflag, AST_FLAG_IN_AUTOLOOP);
 
+	/* Restore subroutine flag */
+	ast_set2_flag(ast_channel_flags(chan), saved_in_subroutine, AST_FLAG_SUBROUTINE_EXEC);
+
 	/* Restore non-hangup softhangup flags. */
 	if (saved_hangup_flags) {
 		ast_softhangup_nolock(chan, saved_hangup_flags);
@@ -1106,6 +1121,7 @@
 	int res;
 	int priority;
 	int old_autoloopflag;
+	int old_in_subroutine;
 	int old_priority;
 	const char *old_context;
 	const char *old_extension;
@@ -1154,6 +1170,9 @@
 	old_autoloopflag = ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP);
 	ast_set_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP);
 
+	/* Save subroutine flag */
+	old_in_subroutine = ast_test_flag(ast_channel_flags(chan), AST_FLAG_SUBROUTINE_EXEC);
+
 	/* Save previous location, since we're going to change it */
 	old_context = ast_strdupa(ast_channel_context(chan));
 	old_extension = ast_strdupa(ast_channel_exten(chan));
@@ -1246,6 +1265,9 @@
 
 	/* Restore autoloop flag */
 	ast_set2_flag(ast_channel_flags(chan), old_autoloopflag, AST_FLAG_IN_AUTOLOOP);
+
+	/* Restore subroutine flag */
+	ast_set2_flag(ast_channel_flags(chan), old_in_subroutine, AST_FLAG_SUBROUTINE_EXEC);
 	ast_channel_unlock(chan);
 
 	return RESULT_SUCCESS;
Index: apps/app_macro.c
===================================================================
--- apps/app_macro.c	(revision 422438)
+++ apps/app_macro.c	(working copy)
@@ -248,6 +248,7 @@
 	char *save_macro_context;
 	char *save_macro_priority;
 	char *save_macro_offset;
+	int save_in_subroutine;
 	struct ast_datastore *macro_store = ast_channel_datastore_find(chan, &macro_ds_info, NULL);
 
 	if (ast_strlen_zero(data)) {
@@ -355,6 +356,9 @@
 
 	pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc);
 
+	save_in_subroutine = ast_test_flag(ast_channel_flags(chan), AST_FLAG_SUBROUTINE_EXEC);
+	ast_set_flag(ast_channel_flags(chan), AST_FLAG_SUBROUTINE_EXEC);
+
 	/* Setup environment for new run */
 	ast_channel_exten_set(chan, "s");
 	ast_channel_context_set(chan, fullmacro);
@@ -513,6 +517,7 @@
 	snprintf(depthc, sizeof(depthc), "%d", depth);
 	pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc);
 	ast_set2_flag(ast_channel_flags(chan), autoloopflag, AST_FLAG_IN_AUTOLOOP);
+	ast_set2_flag(ast_channel_flags(chan), save_in_subroutine, AST_FLAG_SUBROUTINE_EXEC);
 
   	for (x = 1; x < argc; x++) {
   		/* Restore old arguments and delete ours */
Index: main/cdr.c
===================================================================
--- main/cdr.c	(revision 422438)
+++ main/cdr.c	(working copy)
@@ -692,6 +692,8 @@
 		AST_STRING_FIELD(bridge);           /*!< The bridge the party A happens to be in. */
 		AST_STRING_FIELD(appl);             /*!< The last accepted application party A was in */
 		AST_STRING_FIELD(data);             /*!< The data for the last accepted application party A was in */
+		AST_STRING_FIELD(context);          /*!< The accepted context for Party A */
+		AST_STRING_FIELD(exten);            /*!< The accepted extension for Party A */
 	);
 	struct cdr_object *next;                /*!< The next CDR object in the chain */
 	struct cdr_object *last;                /*!< The last CDR object in the chain */
@@ -1115,8 +1117,8 @@
 		ast_copy_string(cdr_copy->uniqueid, party_a->uniqueid, sizeof(cdr_copy->uniqueid));
 		ast_copy_string(cdr_copy->lastapp, it_cdr->appl, sizeof(cdr_copy->lastapp));
 		ast_copy_string(cdr_copy->lastdata, it_cdr->data, sizeof(cdr_copy->lastdata));
-		ast_copy_string(cdr_copy->dst, party_a->exten, sizeof(cdr_copy->dst));
-		ast_copy_string(cdr_copy->dcontext, party_a->context, sizeof(cdr_copy->dcontext));
+		ast_copy_string(cdr_copy->dst, it_cdr->exten, sizeof(cdr_copy->dst));
+		ast_copy_string(cdr_copy->dcontext, it_cdr->context, sizeof(cdr_copy->dcontext));
 
 		/* Party B */
 		if (party_b) {
@@ -1353,6 +1355,17 @@
 		cdr_object_check_party_a_hangup(cdr);
 		return 0;
 	}
+
+	/*
+	 * Only record the context and extension if we aren't in a subroutine, or if
+	 * we are executing hangup logic.
+	 */
+	if (!ast_test_flag(&snapshot->flags, AST_FLAG_SUBROUTINE_EXEC)
+		|| ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {
+		ast_string_field_set(cdr, context, snapshot->context);
+		ast_string_field_set(cdr, exten, snapshot->exten);
+	}
+
 	cdr_object_swap_snapshot(&cdr->party_a, snapshot);
 
 	/* When Party A is originated to an application and the application exits, the stack
