Deal with padding inside .gnu_debuglink section being non-null. Not part of build.
authordbaron@dbaron.org
Mon, 05 May 2008 14:51:11 -0700
changeset 14960 2edd346a074c3f6c94ad075e3de02a57eae0414f
parent 14959 dbb97ba62f78e837e7e55cd3018a0a8fc8ca28ae
child 14961 f14f6345f7bec120ba8f2b42c5745b9fb32aa59b
push idunknown
push userunknown
push dateunknown
milestone1.9pre
Deal with padding inside .gnu_debuglink section being non-null. Not part of build.
tools/rb/fix-linux-stack.pl
--- a/tools/rb/fix-linux-stack.pl
+++ b/tools/rb/fix-linux-stack.pl
@@ -31,17 +31,17 @@
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
-# $Id: fix-linux-stack.pl,v 1.15 2007/06/20 22:01:17 dbaron%dbaron.org Exp $
+# $Id: fix-linux-stack.pl,v 1.16 2008/05/05 21:51:11 dbaron%dbaron.org Exp $
 #
 # This script uses addr2line (part of binutils) to process the output of
 # nsTraceRefcnt's Linux stack walking code.  This is useful for two
 # things:
 #  (1) Getting line number information out of
 #      |nsTraceRefcntImpl::WalkTheStack|'s output in debug builds.
 #  (2) Getting function names out of |nsTraceRefcntImpl::WalkTheStack|'s
 #      output on optimized builds (where it mostly prints UNKNOWN
@@ -178,24 +178,34 @@ sub separate_debug_file_for($) {
 
     my $hash;
     if ($endian eq 'little') {
         $hash = ($hash_bytes[3] << 24) | ($hash_bytes[2] << 16) | ($hash_bytes[1] << 8) | $hash_bytes[0];
     } else {
         $hash = ($hash_bytes[0] << 24) | ($hash_bytes[1] << 16) | ($hash_bytes[2] << 8) | $hash_bytes[3];
     }
 
-    my $old_num = $#chars;
-    while ($chars[$#chars] eq '00') {
-        pop @chars;
+    # The string ends with a null-terminator and then 0 to three bytes
+    # of padding to fill the current 32-bit unit.  (This padding is
+    # usually null bytes, but I've seen null-null-H, on Ubuntu x86_64.)
+    my $terminator = 1;
+    while ($chars[$terminator] ne '00') {
+        if ($terminator == $#chars) {
+            print STDERR "Warning: missing null terminator in " .
+                         ".gnu_debuglink section of $file.\n";
+            return '';
+        }
+        ++$terminator;
     }
-    if ($old_num == $#chars || $old_num - 4 > $#chars) {
-        print STDERR "Warning: malformed .gnu_debuglink section in $file.\n";
+    if ($#chars - $terminator > 3) {
+        print STDERR "Warning: Excess padding in .gnu_debuglink section " .
+                     "of $file.\n";
         return '';
     }
+    $#chars = $terminator - 1;
 
     my $basename = join('', map { chr(hex($_)) } @chars);
 
     # Now $basename and $hash represent the information in the
     # .gnu_debuglink section.
     #printf STDERR "%x: %s\n", $hash, $basename;
 
     my @possible_results = (