Bug 1642121 - Remove directory dependence of GDB init files. r=nalexander
☠☠ backed out by 995cb36e46d4 ☠ ☠
authorSteve Fink <sfink@mozilla.com>
Mon, 15 Jun 2020 03:27:49 +0000
changeset 535643 df0d6b993ad6feb4ebe87c69d630015466dbfeb5
parent 535642 6343210ca9117911824175ac7dc3c873d804e290
child 535644 995cb36e46d49d74ec262dc7d85b4fb3497cd8f0
push id118988
push usersfink@mozilla.com
push dateMon, 15 Jun 2020 03:29:12 +0000
treeherderautoland@df0d6b993ad6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnalexander
bugs1642121
milestone79.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1642121 - Remove directory dependence of GDB init files. r=nalexander I wrote this patch to address two problems: 1. if I do `mach run` from a directory other than $topsrcdir, $objdir, or $objdir/dist/bin, then .gdbinit will not be loaded. 2. Debugging the firefox binary will never load the JS prettyprinters in any case. I believe this patch fixes other problems as well, such as .gdbinit_python not being found, and the gdbpp pretty-printers not getting loaded in various situations. The main changes of this patch are: 1. Move .gdbinit into build/ (and $objdir/build/) to delay it from getting loaded until the search path is configured. 2. Move libxul.so-gdb.py into the correct directory. 3. Use either libxul.so-gdb.py or js-gdb.py to configure the correct search path then load .gdbinit, and have .gdbinit load all of the pretty-printers (Gecko and JS). 4. Use a single preprocessed file to configure the source directory. Use relative paths within the objdir for everything else. Differential Revision: https://phabricator.services.mozilla.com/D77589
.flake8
.gdbinit
.gdbinit_python
build/.gdbinit
build/.gdbinit.loader
build/.gdbinit_python.in
build/moz.build
js/src/gdb/README
js/src/shell/js-gdb.py
js/src/shell/js-gdb.py.in
js/src/shell/moz.build
toolkit/library/libxul.so-gdb.py
toolkit/library/libxul.so-gdb.py.in
toolkit/library/moz.build
--- a/.flake8
+++ b/.flake8
@@ -124,8 +124,12 @@ per-file-ignores =
     toolkit/components/telemetry/**: F821
     tools/tryselect/**: F821
     testing/firefox-ui/tests/functional/safebrowsing/test_initial_download.py: F821
     testing/gtest/rungtests.py: F633
     testing/marionette/**: F821
     testing/mochitest/**: F821
     testing/xpcshell/**: F633, F821
     xpcom/idl-parser/xpidl/**: F633, F821
+
+builtins =
+    # For GDB extensions
+    gdb
deleted file mode 100644
--- a/.gdbinit_python
+++ /dev/null
@@ -1,5 +0,0 @@
-python
-import sys
-sys.path.append('python/gdbpp/')
-import gdbpp
-end
rename from .gdbinit
rename to build/.gdbinit
--- a/.gdbinit
+++ b/build/.gdbinit
@@ -1,15 +1,13 @@
-# .gdbinit file for debugging Mozilla
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-# You may need to put an 'add-auto-load-safe-path' command in your
-# $HOME/.gdbinit file to get GDB to trust this file. If your builds are
-# generally in $HOME/moz, then you can say:
-#
-#  add-auto-load-safe-path ~/moz
+# This file is loaded by .gdbinit
 
 # Don't stop for the SIG32/33/etc signals that Flash produces
 handle SIG32 noprint nostop pass
 handle SIG33 noprint nostop pass
 handle SIGPIPE noprint nostop pass
 
 # Don't stop for certain other signals where it's not useful,
 # such as the SIG64 signals triggered by the Linux
@@ -166,17 +164,17 @@ define ptarray
                 printf "nsTArray capacity = %u\n", $capacity
                 printf "Element "
                 whatis *$elts
         end
 end
 
 document ptarray
         Prints nsTArray information.
-        Syntax: ptarray   
+        Syntax: ptarray
         Note: idx, idx1 and idx2 must be in acceptable range [0...size()-1].
         Examples:
         ptarray a - Prints tarray content, size, capacity and T typedef
         ptarray a 0 - Prints element[idx] from tarray
         ptarray a 1 2 - Prints elements in range [idx1..idx2] from tarray
 end
 
 define js
@@ -193,10 +191,8 @@ end
 
 define ftl
   call $arg0->DumpFrameTreeLimited()
 end
 
 define ftlp
   call $arg0->DumpFrameTreeLimitedInCSSPixels()
 end
-
-source .gdbinit_python
copy from .gdbinit
copy to build/.gdbinit.loader
--- a/.gdbinit
+++ b/build/.gdbinit.loader
@@ -1,202 +1,24 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
 # .gdbinit file for debugging Mozilla
 
 # You may need to put an 'add-auto-load-safe-path' command in your
 # $HOME/.gdbinit file to get GDB to trust this file. If your builds are
 # generally in $HOME/moz, then you can say:
 #
 #  add-auto-load-safe-path ~/moz
 
-# Don't stop for the SIG32/33/etc signals that Flash produces
-handle SIG32 noprint nostop pass
-handle SIG33 noprint nostop pass
-handle SIGPIPE noprint nostop pass
-
-# Don't stop for certain other signals where it's not useful,
-# such as the SIG64 signals triggered by the Linux
-# sandboxing code on older kernels.
-handle SIG38 noprint nostop pass
-handle SIG64 noprint nostop pass
-handle SIGSYS noprint nostop pass
-
-# Show the concrete types behind nsIFoo
-set print object on
-
-# run when using the auto-solib-add trick
-define prun
-        tbreak main
-        run
-	set auto-solib-add 0
-        cont
-end
-
-# run -mail, when using the auto-solib-add trick
-define pmail
-        tbreak main
-        run -mail
-	set auto-solib-add 0
-        cont
-end
-
-# Define a "pu" command to display PRUnichar * strings (100 chars max)
-# Also allows an optional argument for how many chars to print as long as
-# it's less than 100.
-define pu
-  set $uni = $arg0
-  if $argc == 2
-    set $limit = $arg1
-    if $limit > 100
-      set $limit = 100
-    end
-  else
-    set $limit = 100
-  end
-  # scratch array with space for 100 chars plus null terminator.  Make
-  # sure to not use ' ' as the char so this copy/pastes well.
-  set $scratch = "____________________________________________________________________________________________________"
-  set $i = 0
-  set $scratch_idx = 0
-  while (*$uni && $i++ < $limit)
-    if (*$uni < 0x80)
-      set $scratch[$scratch_idx++] = *(char*)$uni++
-    else
-      if ($scratch_idx > 0)
-	set $scratch[$scratch_idx] = '\0'
-	print $scratch
-	set $scratch_idx = 0
-      end
-      print /x *(short*)$uni++
-    end
-  end
-  if ($scratch_idx > 0)
-    set $scratch[$scratch_idx] = '\0'
-    print $scratch
-  end
-end
-
-# Define a "ps" command to display subclasses of nsAC?String.  Note that
-# this assumes strings as of Gecko 1.9 (well, and probably a few
-# releases before that as well); going back far enough will get you
-# to string classes that this function doesn't work for.
-define ps
-  set $str = $arg0
-  if (sizeof(*$str.mData) == 1 && ($str.mFlags & 1) != 0)
-    print $str.mData
-  else
-    pu $str.mData $str.mLength
-  end
-end
-
-# Define a "pa" command to display the string value for an nsAtom
-define pa
-  set $atom = $arg0
-  if (sizeof(*((&*$atom)->mString)) == 2)
-    pu (&*$atom)->mString
-  end
-end
-
-# define a "pxul" command to display the type of a XUL element from
-# an nsXULElement* pointer.
-define pxul
-  set $p = $arg0
-  print $p->mNodeInfo.mRawPtr->mInner.mName->mStaticAtom->mString
-end
+# Multiple include guard
+if $_moz_gdbinit_loaded
+  # already loaded
+else
+  set $_moz_gdbinit_loaded=1
 
-# define a "prefcnt" command to display the refcount of an XPCOM obj
-define prefcnt
-  set $p = $arg0
-  print ((nsPurpleBufferEntry*)$p->mRefCnt.mTagged)->mRefCnt
-end
-
-# define a "ptag" command to display the tag name of a content node
-define ptag
-  set $p = $arg0
-  pa $p->mNodeInfo.mRawPtr->mInner.mName
-end
+  source -s build/.gdbinit.body
 
-##
-## nsTArray
-##
-define ptarray
-        if $argc == 0
-                help ptarray
-        else
-                set $size = $arg0.mHdr->mLength
-                set $capacity = $arg0.mHdr->mCapacity
-                set $size_max = $size - 1
-                set $elts = $arg0.Elements()
-        end
-        if $argc == 1
-                set $i = 0
-                while $i < $size
-                        printf "elem[%u]: ", $i
-                        p *($elts + $i)
-                        set $i++
-                end
-        end
-        if $argc == 2
-                set $idx = $arg1
-                if $idx < 0 || $idx > $size_max
-                        printf "idx1, idx2 are not in acceptable range: [0..%u].\n", $size_max
-                else
-                        printf "elem[%u]: ", $idx
-                        p *($elts + $idx)
-                end
-        end
-        if $argc == 3
-          set $start_idx = $arg1
-          set $stop_idx = $arg2
-          if $start_idx > $stop_idx
-            set $tmp_idx = $start_idx
-            set $start_idx = $stop_idx
-            set $stop_idx = $tmp_idx
-          end
-          if $start_idx < 0 || $stop_idx < 0 || $start_idx > $size_max || $stop_idx > $size_max
-            printf "idx1, idx2 are not in acceptable range: [0..%u].\n", $size_max
-          else
-            set $i = $start_idx
-                while $i <= $stop_idx
-                        printf "elem[%u]: ", $i
-                        p *($elts + $i)
-                        set $i++
-                end
-          end
-        end
-        if $argc > 0
-                printf "nsTArray length = %u\n", $size
-                printf "nsTArray capacity = %u\n", $capacity
-                printf "Element "
-                whatis *$elts
-        end
+  # This requires $objdir to have been added to gdb's source directory search
+  # path. Normally this will be done by libxul.so-gdb.py or js-gdb.py.
+  source -s build/.gdbinit.py
 end
-
-document ptarray
-        Prints nsTArray information.
-        Syntax: ptarray   
-        Note: idx, idx1 and idx2 must be in acceptable range [0...size()-1].
-        Examples:
-        ptarray a - Prints tarray content, size, capacity and T typedef
-        ptarray a 0 - Prints element[idx] from tarray
-        ptarray a 1 2 - Prints elements in range [idx1..idx2] from tarray
-end
-
-define js
-  call DumpJSStack()
-end
-
-define ft
-  call $arg0->DumpFrameTree()
-end
-
-define ftp
-  call $arg0->DumpFrameTreeInCSSPixels()
-end
-
-define ftl
-  call $arg0->DumpFrameTreeLimited()
-end
-
-define ftlp
-  call $arg0->DumpFrameTreeLimitedInCSSPixels()
-end
-
-source .gdbinit_python
deleted file mode 100644
--- a/build/.gdbinit_python.in
+++ /dev/null
@@ -1,6 +0,0 @@
-#filter substitution
-python
-import sys
-sys.path.append('@topsrcdir@/python/gdbpp')
-import gdbpp
-end
--- a/build/moz.build
+++ b/build/moz.build
@@ -30,21 +30,21 @@ if CONFIG['MOZ_BUILD_APP'] == 'browser':
     ]
 
 if CONFIG['ENABLE_TESTS'] or CONFIG['MOZ_DMD']:
     FINAL_TARGET_FILES += ['/tools/rb/fix_stacks.py']
 
 if CONFIG['MOZ_DMD']:
     FINAL_TARGET_FILES += ['/memory/replace/dmd/dmd.py']
 
-# Put a useful .gdbinit in the bin directory, to be picked up automatically
-# by GDB when we debug executables there.
-FINAL_TARGET_FILES += ['/.gdbinit']
-FINAL_TARGET_PP_FILES += ['.gdbinit_python.in']
-OBJDIR_FILES += ['!/dist/bin/.gdbinit_python']
+# Put a useful .gdbinit and .gdbinit.py in $objdir/build, to be picked up
+# automatically by GDB via either libxul.so-gdb.py or js-gdb.py.
+OBJDIR_PP_FILES.build += ['.gdbinit.py.in']
+OBJDIR_FILES.build += ['.gdbinit.loader']
+OBJDIR_FILES.build += ['.gdbinit']
 
 # Install the clang-cl runtime library for ASAN next to the binaries we produce.
 if CONFIG['MOZ_ASAN'] and CONFIG['CC_TYPE'] == 'clang-cl':
     FINAL_TARGET_FILES += ['%' + CONFIG['MOZ_CLANG_RT_ASAN_LIB_PATH']]
     FINAL_TARGET_FILES += ['%' + CONFIG['MOZ_CLANG_RT_ASAN_LIB_PATH'].replace(".dll", ".pdb")]
 
 # Install the clang runtime library for ASAN next to the binaries we produce.
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android' and CONFIG['MOZ_ASAN']:
@@ -90,19 +90,16 @@ if CONFIG['MOZ_APP_BASENAME']:
 
     FINAL_TARGET_FILES += ['!application.ini']
     if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android' and CONFIG['MOZ_UPDATER']:
         FINAL_TARGET_PP_FILES += ['update-settings.ini']
 
     GeneratedFile('application.ini.h', script='appini_header.py',
                   inputs=['!application.ini'])
 
-# NOTE: Keep .gdbinit in the topsrcdir for people who run gdb from the topsrcdir.
-OBJDIR_FILES += ['/.gdbinit']
-
 # Put a .lldbinit in the bin directory and the objdir, to be picked up
 # automatically by LLDB when we debug executables using either of those two
 # directories as the current working directory.  The .lldbinit file will
 # load $(topsrcdir)/.lldbinit, which is where the actual debugging commands are.
 DEFINES['topsrcdir'] = TOPSRCDIR
 DEFINES['topobjdir'] = TOPOBJDIR
 FINAL_TARGET_PP_FILES += ['.lldbinit.in']
 OBJDIR_FILES += ['!/dist/bin/.lldbinit']
--- a/js/src/gdb/README
+++ b/js/src/gdb/README
@@ -32,20 +32,20 @@ You can still see the raw form of a valu
 
     (gdb) p/r obj
     $1 = {<js::HandleBase<JSObject*>> = {<No data fields>}, ptr = 0x7fffffffca60}
     (gdb)
 
 You can also use GDB's 'disable pretty-printer' command to turn off
 individual pretty-printers; try 'info pretty-printer' first.
 
-GDB should pick these extensions up automatically when you debug the shell, by
-auto-loading the 'js-gdb.py' file that js/src/shell/Makefile.in places in the
-same directory as the 'js' executable. You may need to add a command like the
-following to your '$HOME/.gdbinit' file:
+GDB should pick these extensions up automatically when you debug the shell or
+the browser, by auto-loading the 'js-gdb.py' file that the build system
+installs alongside the 'js' executable (or 'libxul.so-gdb.py' for the browser).
+You may need to add a command like the following to your '$HOME/.gdbinit' file:
 
     # Tell GDB to trust auto-load files found under ~/moz.
     add-auto-load-safe-path ~/moz
 
 If you do need this, GDB will tell you.
 
 In general, pretty-printers for pointer types include a summary of the
 pointer's referent:
new file mode 100644
--- /dev/null
+++ b/js/src/shell/js-gdb.py
@@ -0,0 +1,17 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+""" GDB Python customization auto-loader for JS shell binary """
+
+# This script will be installed into $objdir/dist/bin. Add $objdir to gdb's
+# source search path and load in the Gecko+JS init file.
+
+from os.path import abspath, dirname
+
+devel_objdir = abspath(os.path.join(dirname(__file__), '..', '..'))
+m = re.search(r'[\w ]+: (.*)', gdb.execute("show dir", False, True))
+if m and devel_objdir not in m.group(1).split(":"):
+    gdb.execute("set dir {}:{}".format(devel_objdir, m.group(1)))
+
+gdb.execute("source -s build/.gdbinit.loader")
deleted file mode 100644
--- a/js/src/shell/js-gdb.py.in
+++ /dev/null
@@ -1,11 +0,0 @@
-""" GDB Python customization auto-loader for js shell """
-#filter substitution
-
-import os.path
-sys.path[0:0] = [os.path.join('@topsrcdir@', 'gdb')]
-
-import mozilla.autoload
-mozilla.autoload.register(gdb.current_objfile())
-
-import mozilla.asmjs
-mozilla.asmjs.install()
--- a/js/src/shell/moz.build
+++ b/js/src/shell/moz.build
@@ -34,16 +34,24 @@ DEFINES['EXPORT_JS_API'] = True
 
 LOCAL_INCLUDES += [
     '!..',
     '..',
 ]
 
 OS_LIBS += CONFIG['EDITLINE_LIBS']
 
+# Prepare module loader JS code for embedding
+GeneratedFile('shellmoduleloader.out.h', 'shellmoduleloader.js',
+              script='../builtin/embedjs.py',
+              entry_point='generate_shellmoduleloader',
+              inputs=[
+                  '../js.msg',
+                  'ModuleLoader.js',
+              ])
+
 # Place a GDB Python auto-load file next to the shell executable, both in
 # the build directory and in the dist/bin directory.
-DEFINES['topsrcdir'] = '%s/js/src' % TOPSRCDIR
-FINAL_TARGET_PP_FILES += ['js-gdb.py.in']
+FINAL_TARGET_FILES += ['js-gdb.py']
 OBJDIR_FILES.js.src.shell += ['!/dist/bin/js-gdb.py']
 
 # People expect the js shell to wind up in the top-level JS dir.
 OBJDIR_FILES.js.src += ['!/dist/bin/js%s' % CONFIG['BIN_SUFFIX']]
new file mode 100644
--- /dev/null
+++ b/toolkit/library/libxul.so-gdb.py
@@ -0,0 +1,40 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+""" GDB Python customization auto-loader for libxul """
+
+import re
+
+from os.path import (
+    abspath,
+    dirname,
+    exists
+)
+
+# Add the toplevel objdir to the gdb source search path.
+
+# In development builds, $objdir/dist/bin/libxul.so is a symlink to
+# $objdir/toolkit/library/build/libxul.so, and the latter path is what gdb uses
+# to search for gdb scripts.
+#
+# For artifact builds, libxul.so will be a regular file in $objdir/dist/bin.
+# Look both places.
+
+libxul_dir = dirname(__file__)
+objdir = None
+for relpath in ("../../..", "../.."):
+    objdir = abspath(libxul_dir + "/" + relpath)
+    if exists(objdir + "/build/.gdbinit"):
+        break
+else:
+    gdb.write("Warning: Gecko objdir not found\n")
+
+if objdir is not None:
+    m = re.search(r'[\w ]+: (.*)', gdb.execute("show dir", False, True))
+    if m and objdir not in m.group(1).split(":"):
+        gdb.execute("set dir {}:{}".format(objdir, m.group(1)))
+
+    # When running from a random directory, the toplevel Gecko .gdbinit may
+    # not have been loaded. Load it now.
+    gdb.execute("source -s build/.gdbinit.loader")
deleted file mode 100644
--- a/toolkit/library/libxul.so-gdb.py.in
+++ /dev/null
@@ -1,8 +0,0 @@
-""" GDB Python customization auto-loader for libxul """
-#filter substitution
-
-import os.path
-sys.path[0:0] = [os.path.join('@topsrcdir@', 'js', 'src', 'gdb')]
-
-import mozilla.autoload
-mozilla.autoload.register(gdb.current_objfile())
--- a/toolkit/library/moz.build
+++ b/toolkit/library/moz.build
@@ -85,22 +85,22 @@ def Libxul(name, output_category=None):
     if CONFIG['OS_ARCH'] == 'Linux' and CONFIG['OS_TARGET'] != 'Android':
         GeneratedFile('symverscript', script='/build/gen_symverscript.py',
                       inputs=['../symverscript.in'],
                       flags=['xul%s' % CONFIG['MOZILLA_SYMBOLVERSION']])
         SYMBOLS_FILE = '!symverscript'
 
     # Generate GDB pretty printer-autoload files only on Linux. OSX's GDB is
     # too old to support Python pretty-printers; if this changes, we could
-    # make this 'ifdef GNU_CC'.
+    # make this 'ifdef __GNUC__'.
     if CONFIG['OS_ARCH'] == 'Linux':
         # Create a GDB Python auto-load file alongside the libxul shared library
         # in the build directory.
         DEFINES['topsrcdir'] = TOPSRCDIR
-        OBJDIR_PP_FILES.toolkit.library.gtest += ['../libxul.so-gdb.py.in']
+        OBJDIR_FILES.toolkit.library.build += ['../libxul.so-gdb.py']
 
 
 # The real libxul definition is in ./build/moz.build, but we define a
 # xul library here such that # FINAL_LIBRARY = 'xul' refers to here, which
 # is then linked to both build/libxul and gtest/libxul.
 Library('xul')
 
 STATIC_LIBRARY_NAME = 'xul_s'
@@ -367,9 +367,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wind
 SOURCES += ['!buildid.cpp']
 if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('cocoa', 'uikit'):
     libxul_list = 'XUL'
 else:
     libxul_list = '%sxul_%s' % (
         CONFIG['DLL_PREFIX'], CONFIG['DLL_SUFFIX'].lstrip('.').replace('.','_'))
 GeneratedFile('buildid.cpp', script = 'gen_buildid.py',
               inputs=['!build/%s.list' % libxul_list])
-