[PATCH v2 2/8] makedumpfile: Apply relocation while loading module debuginfo.

Mahesh J Salgaonkar mahesh at linux.vnet.ibm.com
Tue Aug 9 13:42:30 EDT 2011


Hi Ken'ichi,

On 2011-07-29 16:21:04 Fri, Ken'ichi Ohmichi wrote:
> 
> Hi Mahesh,
> 
> On Thu, 28 Jul 2011 16:08:15 +0530
> Mahesh Jagannath Salgaonkar <mahesh at linux.vnet.ibm.com> wrote:
> > > 
> > > If adding the searching method to the blow position and removing the code
> > > from init_dwarf_info(), I guess it makes the code simple.
> > > 
> > > @ process_config_file()
> > >  9402                         if (!set_dwarf_debuginfo(config->module_name,
> > >  9403                                                                 NULL, -1)) {
> > >  9404                                 ERRMSG("Skipping to next Module section\n");
> > >  9405                                 skip_section = 1;
> > >  9406                                 free_config(config);
> > >  9407                                 continue;
> > >  9408                         }
> > >  9409                         << HERE >> 
> > 
> > This may not be the correct place to call search method. We may end up
> > calling search method multiple times for same kernel module. I think
> > moving the search method inside set_dwarf_debuginfo() routine at below
> > position is a better place:
> > 
> > @set_dwarf_debuginfo()
> > 	......
> > 	......
> > 	if (!strcmp(dwarf_info.module_name, "vmlinux") ||
> >                 !strcmp(dwarf_info.module_name, "xen-syms"))
> >                 return TRUE;
> > +	 << HERE >>
> > -        /* check to see whether module debuginfo is available */
> > -        if (!init_dwarf_info())
> > -                return FALSE;
> > -        else
> > -                clean_dwfl_info();
> > 	 return TRUE;
> > }
> > 
> > And then we can remove search routine from init_dwarf_info(). What do
> > you think?
> 
> I think the above change will be good, thanks in advance.

Please find the inline patch below that separates the search method from
init_dwarf_info() function. Please review it and let know your comments.

Thanks,
-Mahesh.
----------

makedumpfile: Move debuginfo search to set_dwarf_debuginfo() routine.

From: Mahesh Salgaonkar <mahesh at linux.vnet.ibm.com>

Move the debuginfo search logic out of init_dwarf_info() function to make
this function more simpler. Now we call search method in set_dwarf_debuginfo
when switch to different module section.

This patch also fixes a BUG where dwarf_info.module_name becomes a stale
pointer after free_config() invocation. This patch now uses strdup() to get
duplicate string and assigns it to dwarf_info.module_name.

Signed-off-by: Mahesh Salgaonkar <mahesh at linux.vnet.ibm.com>
---
 makedumpfile.c |  126 ++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 86 insertions(+), 40 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 35cbed9..fe8e8b0 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -1186,7 +1186,60 @@ clean_dwfl_info(void)
 }
 
 /*
- * Intitialize the dwarf info.
+ * Search module debuginfo.
+ * This function searches for module debuginfo in default debuginfo path for
+ * a given module in dwarf_info.module_name.
+ *
+ * On success, dwarf_info.name_debuginfo is set to absolute path of
+ * module debuginfo.
+ */
+static int
+search_module_debuginfo(void)
+{
+	Dwfl *dwfl = NULL;
+	static char *debuginfo_path = DEFAULT_DEBUGINFO_PATH;
+	static const Dwfl_Callbacks callbacks = {
+		.section_address = dwfl_offline_section_address,
+		.find_debuginfo = dwfl_standard_find_debuginfo,
+		.debuginfo_path = &debuginfo_path,
+	};
+
+	/*
+	 * Check if We already have debuginfo file name with us. If yes,
+	 * then we don't need to proceed with search method.
+	 */
+	if (dwarf_info.name_debuginfo)
+		return TRUE;
+
+	if ((dwfl = dwfl_begin(&callbacks)) == NULL) {
+		ERRMSG("Can't create a handle for a new dwfl session.\n");
+		return FALSE;
+	}
+
+	/* Search for module debuginfo file. */
+	if (dwfl_linux_kernel_report_offline(dwfl,
+						info->system_utsname.release,
+						&dwfl_report_module_p)) {
+		ERRMSG("Can't get Module debuginfo for module '%s'\n",
+					dwarf_info.module_name);
+		dwfl_end(dwfl);
+		return FALSE;
+	}
+	dwfl_report_end(dwfl, NULL, NULL);
+	dwfl_getmodules(dwfl, &process_module, NULL, 0);
+
+	dwfl_end(dwfl);
+	clean_dwfl_info();
+
+	/* Return success if module debuginfo is found. */
+	if (dwarf_info.name_debuginfo)
+		return TRUE;
+
+	return FALSE;
+}
+
+/*
+ * Initialize the dwarf info.
  * Linux kernel module debuginfo are of ET_REL (relocatable) type.
  * This function uses dwfl API's to apply relocation before reading the
  * dwarf information from module debuginfo.
@@ -1198,51 +1251,45 @@ init_dwarf_info(void)
 {
 	Dwfl *dwfl = NULL;
 	int dwfl_fd = -1;
-	static char *debuginfo_path = DEFAULT_DEBUGINFO_PATH;
 	static const Dwfl_Callbacks callbacks = {
 		.section_address = dwfl_offline_section_address,
-		.find_debuginfo = dwfl_standard_find_debuginfo,
-		.debuginfo_path = &debuginfo_path,
 	};
 
 	dwarf_info.elfd = NULL;
 	dwarf_info.dwarfd = NULL;
 
+	 /*
+	  * We already know the absolute path of debuginfo file. Fail if we
+	  * still don't have one. Ideally we should never be in this situation.
+	  */
+	if (!dwarf_info.name_debuginfo) {
+		ERRMSG("Can't find absolute path to debuginfo file.\n");
+		return FALSE;
+	}
+
 	if ((dwfl = dwfl_begin(&callbacks)) == NULL) {
 		ERRMSG("Can't create a handle for a new dwfl session.\n");
 		return FALSE;
 	}
 
-	if (dwarf_info.name_debuginfo) {
-		/* We have absolute path for debuginfo file, use it directly
-		 * instead of searching it through
-		 * dwfl_linux_kernel_report_offline() call.
-		 *
-		 * Open the debuginfo file if it is not already open.
-		 */
-		if (dwarf_info.fd_debuginfo < 0)
-			dwarf_info.fd_debuginfo =
-				open(dwarf_info.name_debuginfo, O_RDONLY);
-
-		dwfl_fd = dup(dwarf_info.fd_debuginfo);
-		if (dwfl_fd < 0) {
-			ERRMSG("Failed to get a duplicate handle for"
-				" debuginfo.\n");
-			goto err_out;
-		}
-		if (dwfl_report_offline(dwfl, dwarf_info.module_name,
-				dwarf_info.name_debuginfo, dwfl_fd) == NULL) {
-			ERRMSG("Failed reading %s: %s\n",
-				dwarf_info.name_debuginfo, dwfl_errmsg (-1));
-			/* dwfl_fd is consumed on success, not on failure */
-			close(dwfl_fd);
-			goto err_out;
-		}
-	} else if (dwfl_linux_kernel_report_offline(dwfl,
-						info->system_utsname.release,
-						&dwfl_report_module_p)) {
-		ERRMSG("Can't get Module debuginfo for module '%s'\n",
-					dwarf_info.module_name);
+	/* Open the debuginfo file if it is not already open.  */
+	if (dwarf_info.fd_debuginfo < 0)
+		dwarf_info.fd_debuginfo =
+			open(dwarf_info.name_debuginfo, O_RDONLY);
+
+	dwfl_fd = dup(dwarf_info.fd_debuginfo);
+	if (dwfl_fd < 0) {
+		ERRMSG("Failed to get a duplicate handle for"
+			" debuginfo.\n");
+		goto err_out;
+	}
+	/* Apply relocations. */
+	if (dwfl_report_offline(dwfl, dwarf_info.module_name,
+			dwarf_info.name_debuginfo, dwfl_fd) == NULL) {
+		ERRMSG("Failed reading %s: %s\n",
+			dwarf_info.name_debuginfo, dwfl_errmsg (-1));
+		/* dwfl_fd is consumed on success, not on failure */
+		close(dwfl_fd);
 		goto err_out;
 	}
 	dwfl_report_end(dwfl, NULL, NULL);
@@ -2522,20 +2569,19 @@ set_dwarf_debuginfo(char *mod_name, char *name_debuginfo, int fd_debuginfo)
 		if (dwarf_info.name_debuginfo)
 			free(dwarf_info.name_debuginfo);
 	}
+	if (dwarf_info.module_name)
+		free(dwarf_info.module_name);
+
 	dwarf_info.fd_debuginfo = fd_debuginfo;
 	dwarf_info.name_debuginfo = name_debuginfo;
-	dwarf_info.module_name = mod_name;
+	dwarf_info.module_name = strdup(mod_name);
 
 	if (!strcmp(dwarf_info.module_name, "vmlinux") ||
 		!strcmp(dwarf_info.module_name, "xen-syms"))
 		return TRUE;
 
 	/* check to see whether module debuginfo is available */
-	if (!init_dwarf_info())
-		return FALSE;
-	else
-		clean_dwfl_info();
-	return TRUE;
+	return search_module_debuginfo();
 }
 
 int




More information about the kexec mailing list