On Wed, Sep 16, 2009 at 04:44:32PM -0600, Bob Montgomery wrote: > John and I think that this code in gdb searches things too many times, > particularly with this patch, but it's a start since it seems to fix the > problem. I'm attaching a new version of the patch, that performs way better when disassembling functions that live in the kernel. (Bob found that the original patch made crash disassemble in-kernel functions at least 3 times slower, but that number will be larger depending on how close the symbol table the function lives in is to the head of the psymtabs list. Module disassembly speed wasn't changed much at all.) With this updated patch, we found the performance penalty of "dis -l" to be marginal. The problem with the original patch is that once the address we want is found in a symbol table, it then looks through the rest of the symbol tables in that objfile for a better match. The original code would then return the best pst out of that objfile (and never get the next pst from ALL_PSYMTABS), but we want to go through the rest of the objfiles just in case, so I moved the return statement outside of the ALL_PSYMTABS loop. But the next pst from ALL_PSYMTABS will not be from a new objfile - so we would wind up traversing the list (minus one element) again, and again, and again... The new patch removes the inner list traversal, and just takes advantage of the fact that we already iterate through every pst via ALL_PSYMTABS. -- +----------------------------------------------------------+ | John Wright <john.wright@xxxxxx> | | HP Mission Critical OS Enablement & Solution Test (MOST) | +----------------------------------------------------------+
commit 86de510c19c32eb7a9d188398b888e61ca1542d5 Author: John Wright <john.wright@xxxxxx> Date: Wed Sep 23 14:45:06 2009 -0600 Fix for dis -l on amd64 modules diff --git a/gdb-6.1.patch b/gdb-6.1.patch index 8db979c..97c0799 100644 --- a/gdb-6.1.patch +++ b/gdb-6.1.patch @@ -11752,3 +11752,71 @@ diff -urp gdb-6.1.orig/gdb/ChangeLog gdb-6.1/gdb/ChangeLog + +/* max size of register name in insn mnemonics. */ +#define MAX_REG_NAME_SIZE 8 +--- gdb-6.1/gdb/symtab.c ++++ gdb-6.1/gdb/symtab.c +@@ -684,6 +684,8 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section) + struct partial_symtab *pst; + struct objfile *objfile; + struct minimal_symbol *msymbol; ++ struct partial_symtab *best_pst = NULL; ++ struct partial_symbol *best_psym = NULL; + + /* If we know that this is not a text address, return failure. This is + necessary because we loop based on texthigh and textlow, which do +@@ -701,9 +703,7 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section) + { + if (pc >= pst->textlow && pc < pst->texthigh) + { +- struct partial_symtab *tpst; +- struct partial_symtab *best_pst = pst; +- struct partial_symbol *best_psym = NULL; ++ struct partial_symbol *p; + + /* An objfile that has its functions reordered might have + many partial symbol tables containing the PC, but +@@ -717,23 +717,17 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section) + return (pst); + + /* The code range of partial symtabs sometimes overlap, so, in +- the loop below, we need to check all partial symtabs and ++ the code below, we need to check all partial symtabs and + find the one that fits better for the given PC address. We + select the partial symtab that contains a symbol whose + address is closest to the PC address. By closest we mean + that find_pc_sect_symbol returns the symbol with address + that is closest and still less than the given PC. */ +- for (tpst = pst; tpst != NULL; tpst = tpst->next) +- { +- if (pc >= tpst->textlow && pc < tpst->texthigh) +- { +- struct partial_symbol *p; +- +- p = find_pc_sect_psymbol (tpst, pc, section); ++ p = find_pc_sect_psymbol (pst, pc, section); + if (p != NULL + && SYMBOL_VALUE_ADDRESS (p) + == SYMBOL_VALUE_ADDRESS (msymbol)) +- return (tpst); ++ return (pst); + if (p != NULL) + { + /* We found a symbol in this partial symtab which +@@ -754,16 +748,12 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section) + > SYMBOL_VALUE_ADDRESS (best_psym)) + { + best_psym = p; +- best_pst = tpst; ++ best_pst = pst; + } + } +- +- } +- } +- return (best_pst); + } + } +- return (NULL); ++ return (best_pst); + } + + /* Find which partial symtab contains PC. Return 0 if none.
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility