mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	Merged revisions 298957 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r298957 | tilghman | 2010-12-17 17:30:55 -0600 (Fri, 17 Dec 2010) | 13 lines Merged revisions 298905 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r298905 | tilghman | 2010-12-17 15:40:56 -0600 (Fri, 17 Dec 2010) | 6 lines Let Asterisk find better backtrace information with libbfd. The menuselect option BETTER_BACKTRACES, if enabled, will use libbfd to search for better symbol information within both the Asterisk binary, as well as loaded modules, to assist when using inline backtraces to track down problems. ........ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@298960 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -46,6 +46,10 @@ else | ||||
|   AST_LIBS+=$(EDITLINE_LIB) -lm | ||||
| endif | ||||
|  | ||||
| ifneq ($(findstring BETTER_BACKTRACES,$(MENUSELECT_CFLAGS)),) | ||||
|   AST_LIBS+=$(BFD_LIB) | ||||
| endif | ||||
|  | ||||
| ifneq ($(findstring darwin,$(OSARCH)),) | ||||
|   AST_LIBS+=-lresolv | ||||
|   ASTLINK=-Xlinker -macosx_version_min -Xlinker 10.4 -Xlinker -undefined -Xlinker dynamic_lookup -force_flat_namespace | ||||
|   | ||||
| @@ -88,7 +88,7 @@ void ao2_bt(void) | ||||
| 	char **strings; | ||||
|  | ||||
| 	c = backtrace(addresses, N1); | ||||
| 	strings = backtrace_symbols(addresses,c); | ||||
| 	strings = ast_bt_get_symbols(addresses,c); | ||||
| 	ast_verbose("backtrace returned: %d\n", c); | ||||
| 	for(i = 0; i < c; i++) { | ||||
| 		ast_verbose("%d: %p %s\n", i, addresses[i], strings[i]); | ||||
|   | ||||
							
								
								
									
										152
									
								
								main/logger.c
									
									
									
									
									
								
							
							
						
						
									
										152
									
								
								main/logger.c
									
									
									
									
									
								
							| @@ -56,6 +56,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | ||||
| #ifdef HAVE_BKTR | ||||
| #include <execinfo.h> | ||||
| #define MAX_BACKTRACE_FRAMES 20 | ||||
| #  if defined(HAVE_DLADDR) && defined(HAVE_BFD) && defined(BETTER_BACKTRACES) | ||||
| #    include <dlfcn.h> | ||||
| #    include <bfd.h> | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| #if defined(__linux__) && !defined(__NR_gettid) | ||||
| @@ -1222,6 +1226,150 @@ void *ast_bt_destroy(struct ast_bt *bt) | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| char **ast_bt_get_symbols(void **addresses, size_t num_frames) | ||||
| { | ||||
| 	char **strings = NULL; | ||||
| #if defined(BETTER_BACKTRACES) | ||||
| 	int stackfr; | ||||
| 	bfd *bfdobj;           /* bfd.h */ | ||||
| 	Dl_info dli;           /* dlfcn.h */ | ||||
| 	long allocsize; | ||||
| 	asymbol **syms = NULL; /* bfd.h */ | ||||
| 	bfd_vma offset;        /* bfd.h */ | ||||
| 	const char *lastslash; | ||||
| 	asection *section; | ||||
| 	const char *file, *func; | ||||
| 	unsigned int line; | ||||
| 	char address_str[128]; | ||||
| 	char msg[1024]; | ||||
| 	size_t strings_size; | ||||
| 	size_t *eachlen; | ||||
| #endif | ||||
|  | ||||
| #if defined(BETTER_BACKTRACES) | ||||
| 	strings_size = num_frames * sizeof(*strings); | ||||
| 	eachlen = ast_calloc(num_frames, sizeof(*eachlen)); | ||||
|  | ||||
| 	if (!(strings = ast_calloc(num_frames, sizeof(*strings)))) { | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	for (stackfr = 0; stackfr < num_frames; stackfr++) { | ||||
| 		int found = 0, symbolcount; | ||||
|  | ||||
| 		msg[0] = '\0'; | ||||
|  | ||||
| 		if (!dladdr(addresses[stackfr], &dli)) { | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		if (strcmp(dli.dli_fname, "asterisk") == 0) { | ||||
| 			char asteriskpath[256]; | ||||
| 			if (!(dli.dli_fname = ast_utils_which("asterisk", asteriskpath, sizeof(asteriskpath)))) { | ||||
| 				/* This will fail to find symbols */ | ||||
| 				ast_log(LOG_DEBUG, "Failed to find asterisk binary for debug symbols.\n"); | ||||
| 				dli.dli_fname = "asterisk"; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		lastslash = strrchr(dli.dli_fname, '/'); | ||||
| 		if (	(bfdobj = bfd_openr(dli.dli_fname, NULL)) && | ||||
| 				bfd_check_format(bfdobj, bfd_object) && | ||||
| 				(allocsize = bfd_get_symtab_upper_bound(bfdobj)) > 0 && | ||||
| 				(syms = ast_malloc(allocsize)) && | ||||
| 				(symbolcount = bfd_canonicalize_symtab(bfdobj, syms))) { | ||||
|  | ||||
| 			if (bfdobj->flags & DYNAMIC) { | ||||
| 				offset = addresses[stackfr] - dli.dli_fbase; | ||||
| 			} else { | ||||
| 				offset = addresses[stackfr] - (void *) 0; | ||||
| 			} | ||||
|  | ||||
| 			for (section = bfdobj->sections; section; section = section->next) { | ||||
| 				if (	!bfd_get_section_flags(bfdobj, section) & SEC_ALLOC || | ||||
| 						section->vma > offset || | ||||
| 						section->size + section->vma < offset) { | ||||
| 					continue; | ||||
| 				} | ||||
|  | ||||
| 				if (!bfd_find_nearest_line(bfdobj, section, syms, offset - section->vma, &file, &func, &line)) { | ||||
| 					continue; | ||||
| 				} | ||||
|  | ||||
| 				/* Stack trace output */ | ||||
| 				found++; | ||||
| 				if ((lastslash = strrchr(file, '/'))) { | ||||
| 					const char *prevslash; | ||||
| 					for (prevslash = lastslash - 1; *prevslash != '/' && prevslash >= file; prevslash--); | ||||
| 					if (prevslash >= file) { | ||||
| 						lastslash = prevslash; | ||||
| 					} | ||||
| 				} | ||||
| 				if (dli.dli_saddr == NULL) { | ||||
| 					address_str[0] = '\0'; | ||||
| 				} else { | ||||
| 					snprintf(address_str, sizeof(address_str), " (%p+%lX)", | ||||
| 						dli.dli_saddr, | ||||
| 						(unsigned long) (addresses[stackfr] - dli.dli_saddr)); | ||||
| 				} | ||||
| 				snprintf(msg, sizeof(msg), "%s:%u %s()%s", | ||||
| 					lastslash ? lastslash + 1 : file, line, | ||||
| 					S_OR(func, "???"), | ||||
| 					address_str); | ||||
|  | ||||
| 				break; /* out of section iteration */ | ||||
| 			} | ||||
| 		} | ||||
| 		if (bfdobj) { | ||||
| 			bfd_close(bfdobj); | ||||
| 			if (syms) { | ||||
| 				ast_free(syms); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		/* Default output, if we cannot find the information within BFD */ | ||||
| 		if (!found) { | ||||
| 			if (dli.dli_saddr == NULL) { | ||||
| 				address_str[0] = '\0'; | ||||
| 			} else { | ||||
| 				snprintf(address_str, sizeof(address_str), " (%p+%lX)", | ||||
| 					dli.dli_saddr, | ||||
| 					(unsigned long) (addresses[stackfr] - dli.dli_saddr)); | ||||
| 			} | ||||
| 			snprintf(msg, sizeof(msg), "%s %s()%s", | ||||
| 				lastslash ? lastslash + 1 : dli.dli_fname, | ||||
| 				S_OR(dli.dli_sname, "<unknown>"), | ||||
| 				address_str); | ||||
| 		} | ||||
|  | ||||
| 		if (!ast_strlen_zero(msg)) { | ||||
| 			char **tmp; | ||||
| 			eachlen[stackfr] = strlen(msg); | ||||
| 			if (!(tmp = ast_realloc(strings, strings_size + eachlen[stackfr] + 1))) { | ||||
| 				ast_free(strings); | ||||
| 				strings = NULL; | ||||
| 				break; /* out of stack frame iteration */ | ||||
| 			} | ||||
| 			strings = tmp; | ||||
| 			strings[stackfr] = (char *) strings + strings_size; | ||||
| 			ast_copy_string(strings[stackfr], msg, eachlen[stackfr] + 1); | ||||
| 			strings_size += eachlen[stackfr] + 1; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (strings) { | ||||
| 		/* Recalculate the offset pointers */ | ||||
| 		strings[0] = (char *) strings + num_frames * sizeof(*strings); | ||||
| 		for (stackfr = 1; stackfr < num_frames; stackfr++) { | ||||
| 			strings[stackfr] = strings[stackfr - 1] + eachlen[stackfr - 1] + 1; | ||||
| 		} | ||||
| 	} | ||||
| #else /* !defined(BETTER_BACKTRACES) */ | ||||
| 	strings = backtrace_symbols(addresses, num_frames); | ||||
| #endif /* defined(BETTER_BACKTRACES) */ | ||||
| 	return strings; | ||||
| } | ||||
|  | ||||
| #endif /* HAVE_BKTR */ | ||||
|  | ||||
| void ast_backtrace(void) | ||||
| @@ -1236,7 +1384,7 @@ void ast_backtrace(void) | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if ((strings = backtrace_symbols(bt->addresses, bt->num_frames))) { | ||||
| 	if ((strings = ast_bt_get_symbols(bt->addresses, bt->num_frames))) { | ||||
| 		ast_debug(1, "Got %d backtrace record%c\n", bt->num_frames, bt->num_frames != 1 ? 's' : ' '); | ||||
| 		for (i = 3; i < bt->num_frames - 2; i++) { | ||||
| 			ast_log(LOG_DEBUG, "#%d: [%p] %s\n", i - 3, bt->addresses[i], strings[i]); | ||||
| @@ -1251,7 +1399,7 @@ void ast_backtrace(void) | ||||
| 	ast_bt_destroy(bt); | ||||
| #else | ||||
| 	ast_log(LOG_WARNING, "Must run configure with '--with-execinfo' for stack backtraces.\n"); | ||||
| #endif | ||||
| #endif /* defined(HAVE_BKTR) */ | ||||
| } | ||||
|  | ||||
| void __ast_verbose_ap(const char *file, int line, const char *func, const char *fmt, va_list ap) | ||||
|   | ||||
| @@ -3680,6 +3680,8 @@ int ast_say_date_with_format_en(struct ast_channel *chan, time_t t, const char * | ||||
| 	int res=0, offset, sndoffset; | ||||
| 	char sndfile[256], nextmsg[256]; | ||||
|  | ||||
| 	ast_backtrace(); | ||||
|  | ||||
| 	if (format == NULL) | ||||
| 		format = "ABdY 'digits/at' IMp"; | ||||
|  | ||||
|   | ||||
							
								
								
									
										22
									
								
								main/utils.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								main/utils.c
									
									
									
									
									
								
							| @@ -29,6 +29,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | ||||
|  | ||||
| #include <ctype.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/stat.h> | ||||
|  | ||||
| #ifdef HAVE_DEV_URANDOM | ||||
| #include <fcntl.h> | ||||
| @@ -739,7 +740,7 @@ static void append_backtrace_information(struct ast_str **str, struct ast_bt *bt | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if ((symbols = backtrace_symbols(bt->addresses, bt->num_frames))) { | ||||
| 	if ((symbols = ast_bt_get_symbols(bt->addresses, bt->num_frames))) { | ||||
| 		int frame_iterator; | ||||
| 		 | ||||
| 		for (frame_iterator = 0; frame_iterator < bt->num_frames; ++frame_iterator) { | ||||
| @@ -2081,3 +2082,22 @@ int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, co | ||||
| 	return res; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size) | ||||
| { | ||||
| 	const char *envPATH = getenv("PATH"); | ||||
| 	char *tpath, *path; | ||||
| 	struct stat unused; | ||||
| 	if (!envPATH) { | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	tpath = ast_strdupa(envPATH); | ||||
| 	while ((path = strsep(&tpath, ":"))) { | ||||
| 		snprintf(fullpath, fullpath_size, "%s/%s", path, binary); | ||||
| 		if (!stat(fullpath, &unused)) { | ||||
| 			return fullpath; | ||||
| 		} | ||||
| 	} | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user