Bug 1100851 - Tweak DMD to account for the fact that $DMD can now be undefined. r=glandium.
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 27 Nov 2014 21:04:46 -0800
changeset 246761 edd717f27f37f3cf9d7fbcd99a13417b38b11f66
parent 246760 36679c5f568edfd9b3318b503b637b3144beb79d
child 246762 bd3c5d90a40cf82afeb6dd08a8a3280b381da92a
push id698
push userjlund@mozilla.com
push dateMon, 23 Mar 2015 22:08:11 +0000
treeherdermozilla-release@b0c0ae7b02a3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglandium
bugs1100851
milestone37.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 1100851 - Tweak DMD to account for the fact that $DMD can now be undefined. r=glandium. Now that defining $DMD is no longer necessary to run DMD, this patch does the following. - Removes all the places where we set DMD=1 (test harnesses, etc.) - Still handles DMD=1, for backwards compatibility. - Prints "$DMD is undefined" at DMD start-up if appropriate. - Writes a |null| value for |dmdEnvVar| in the JSON if $DMD is undefined. Bumps the DMD output version number accordingly. - Changes a bunch of the test files accordingly, including changing the mode of script-ignore-alloc-fns.json in order to test a case where $DMD is undefined.
build/automation.py.in
build/automationutils.py
build/mobile/remoteautomation.py
memory/replace/dmd/DMD.cpp
memory/replace/dmd/DMD.h
memory/replace/dmd/dmd.py
memory/replace/dmd/test/script-diff-dark-matter-expected.txt
memory/replace/dmd/test/script-diff-dark-matter1.json
memory/replace/dmd/test/script-diff-dark-matter2.json
memory/replace/dmd/test/script-diff-live-expected.txt
memory/replace/dmd/test/script-diff-live1.json
memory/replace/dmd/test/script-diff-live2.json
memory/replace/dmd/test/script-ignore-alloc-fns-expected.txt
memory/replace/dmd/test/script-ignore-alloc-fns.json
memory/replace/dmd/test/script-max-frames-1-expected.txt
memory/replace/dmd/test/script-max-frames-3-expected.txt
memory/replace/dmd/test/script-max-frames-8-expected.txt
memory/replace/dmd/test/script-max-frames.json
memory/replace/dmd/test/script-sort-by-req-expected.txt
memory/replace/dmd/test/script-sort-by-slop-expected.txt
memory/replace/dmd/test/script-sort-by-usable-expected.txt
memory/replace/dmd/test/script-sort-by.json.gz
memory/replace/dmd/test/test_dmd.js
python/mozbuild/mozbuild/mach_commands.py
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -482,17 +482,16 @@ class Automation(object):
         ldLibraryPath = ldLibraryPath + ":" + env[envVar]
       env[envVar] = ldLibraryPath
     elif self.IS_WIN32:
       env["PATH"] = env["PATH"] + ";" + str(ldLibraryPath)
       dmdLibrary = "dmd.dll"
       preloadEnvVar = "MOZ_REPLACE_MALLOC_LIB"
 
     if dmdPath and dmdLibrary and preloadEnvVar:
-      env['DMD'] = '1'
       env[preloadEnvVar] = os.path.join(dmdPath, dmdLibrary)
 
     if crashreporter and not debugger:
       env['MOZ_CRASHREPORTER_NO_REPORT'] = '1'
       env['MOZ_CRASHREPORTER'] = '1'
     else:
       env['MOZ_CRASHREPORTER_DISABLE'] = '1'
 
--- a/build/automationutils.py
+++ b/build/automationutils.py
@@ -384,17 +384,16 @@ def environment(xrePath, env=None, crash
     preloadEnvVar = "MOZ_REPLACE_MALLOC_LIB"
   if envVar:
     envValue = ((env.get(envVar), str(ldLibraryPath))
                 if mozinfo.isWin
                 else (ldLibraryPath, dmdPath, env.get(envVar)))
     env[envVar] = os.path.pathsep.join([path for path in envValue if path])
 
   if dmdPath and dmdLibrary and preloadEnvVar:
-    env['DMD'] = '1'
     env[preloadEnvVar] = os.path.join(dmdPath, dmdLibrary)
 
   # crashreporter
   env['GNOME_DISABLE_CRASH_DIALOG'] = '1'
   env['XRE_NO_WINDOWS_CRASH_DIALOG'] = '1'
   env['NS_TRACE_MALLOC_DISABLE_STACKS'] = '1'
 
   if crashreporter and not debugger:
--- a/build/mobile/remoteautomation.py
+++ b/build/mobile/remoteautomation.py
@@ -55,17 +55,16 @@ class RemoteAutomation(Automation):
     # Set up what we need for the remote environment
     def environment(self, env=None, xrePath=None, crashreporter=True, debugger=False, dmdPath=None, lsanPath=None):
         # Because we are running remote, we don't want to mimic the local env
         # so no copying of os.environ
         if env is None:
             env = {}
 
         if dmdPath:
-            env['DMD'] = '1'
             env['MOZ_REPLACE_MALLOC_LIB'] = os.path.join(dmdPath, 'libdmd.so')
 
         # Except for the mochitest results table hiding option, which isn't
         # passed to runtestsremote.py as an actual option, but through the
         # MOZ_HIDE_RESULTS_TABLE environment variable.
         if 'MOZ_HIDE_RESULTS_TABLE' in os.environ:
             env['MOZ_HIDE_RESULTS_TABLE'] = os.environ['MOZ_HIDE_RESULTS_TABLE']
 
--- a/memory/replace/dmd/DMD.cpp
+++ b/memory/replace/dmd/DMD.cpp
@@ -1371,24 +1371,28 @@ Options::GetBool(const char* aArg, const
 // - Why that size?  Because it's *much* faster but only moderately less precise
 //   than a size of 1.
 // - Why prime?  Because it makes our sampling more random.  If we used a size
 //   of 4096, for example, then our alloc counter would only take on even
 //   values, because jemalloc always rounds up requests sizes.  In contrast, a
 //   prime size will explore all possible values of the alloc counter.
 //
 Options::Options(const char* aDMDEnvVar)
-  : mDMDEnvVar(InfallibleAllocPolicy::strdup_(aDMDEnvVar))
+  : mDMDEnvVar(aDMDEnvVar ? InfallibleAllocPolicy::strdup_(aDMDEnvVar)
+                          : nullptr)
   , mMode(DarkMatter)
   , mSampleBelowSize(4093, 100 * 100 * 1000)
   , mMaxFrames(StackTrace::MaxFrames, StackTrace::MaxFrames)
   , mShowDumpStats(false)
 {
+  // It's no longer necessary to set the DMD env var to "1" if you want default
+  // options (you can leave it undefined) but we still accept "1" for
+  // backwards compatibility.
   char* e = mDMDEnvVar;
-  if (strcmp(e, "1") != 0) {
+  if (e && strcmp(e, "1") != 0) {
     bool isEnd = false;
     while (!isEnd) {
       // Consume leading whitespace.
       while (isspace(*e)) {
         e++;
       }
 
       // Save the start of the arg.
@@ -1480,22 +1484,22 @@ NopStackWalkCallback(uint32_t aFrameNumb
 static void
 Init(const malloc_table_t* aMallocTable)
 {
   gMallocTable = aMallocTable;
 
   // DMD is controlled by the |DMD| environment variable.
   const char* e = getenv("DMD");
 
-  if (!e) {
-    e = "1";
+  if (e) {
+    StatusMsg("$DMD = '%s'\n", e);
+  } else {
+    StatusMsg("$DMD is undefined\n", e);
   }
 
-  StatusMsg("$DMD = '%s'\n", e);
-
   // Parse $DMD env var.
   gOptions = InfallibleAllocPolicy::new_<Options>(e);
 
 #ifdef XP_MACOSX
   // On Mac OS X we need to call StackWalkInitCriticalAddress() very early
   // (prior to the creation of any mutexes, apparently) otherwise we can get
   // hangs when getting stack traces (bug 821577).  But
   // StackWalkInitCriticalAddress() isn't exported from xpcom/, so instead we
@@ -1570,17 +1574,17 @@ DMDFuncs::ReportOnAlloc(const void* aPtr
 
 //---------------------------------------------------------------------------
 // DMD output
 //---------------------------------------------------------------------------
 
 // The version number of the output format. Increment this if you make
 // backwards-incompatible changes to the format. See DMD.h for the version
 // history.
-static const int kOutputVersionNumber = 2;
+static const int kOutputVersionNumber = 3;
 
 // Note that, unlike most SizeOf* functions, this function does not take a
 // |mozilla::MallocSizeOf| argument.  That's because those arguments are
 // primarily to aid DMD track heap blocks... but DMD deliberately doesn't track
 // heap blocks it allocated for itself!
 //
 // SizeOfInternal should be called while you're holding the state lock and
 // while intercepts are blocked; SizeOf acquires the lock and blocks
@@ -1730,29 +1734,36 @@ AnalyzeImpl(UniquePtr<JSONWriteFunc> aWr
 
   JSONWriter writer(Move(aWriter));
   writer.Start();
   {
     writer.IntProperty("version", kOutputVersionNumber);
 
     writer.StartObjectProperty("invocation");
     {
-      writer.StringProperty("dmdEnvVar", gOptions->DMDEnvVar());
+      const char* var = gOptions->DMDEnvVar();
+      if (var) {
+        writer.StringProperty("dmdEnvVar", var);
+      } else {
+        writer.NullProperty("dmdEnvVar");
+      }
+
       const char* mode;
       if (gOptions->IsLiveMode()) {
         mode = "live";
       } else if (gOptions->IsDarkMatterMode()) {
         mode = "dark-matter";
       } else if (gOptions->IsCumulativeMode()) {
         mode = "cumulative";
       } else {
         MOZ_ASSERT(false);
         mode = "(unknown DMD mode)";
       }
       writer.StringProperty("mode", mode);
+
       writer.IntProperty("sampleBelowSize", gOptions->SampleBelowSize());
     }
     writer.EndObject();
 
     StatusMsg("  Constructing the heap block list...\n");
 
     ToIdStringConverter isc;
 
--- a/memory/replace/dmd/DMD.h
+++ b/memory/replace/dmd/DMD.h
@@ -143,23 +143,26 @@ ClearReports()
 // omitting properties whenever possible.
 //
 // {
 //   // The version number of the format, which will be incremented each time
 //   // backwards-incompatible changes are made. A mandatory integer.
 //   //
 //   // Version history:
 //   // - 1: The original format. Implemented in bug 1044709.
-//   // - 2: Added the "mode" field under "invocation". Added in bug 1094552.
-//   "version": 2,
+//   // - 2: Added the "mode" property under "invocation". Added in bug 1094552.
+//   // - 3: The "dmdEnvVar" property under "invocation" can now be |null| if
+//   //      the |DMD| environment variable is not defined. Done in bug 1100851.
+//   "version": 3,
 //
 //   // Information about how DMD was invoked. A mandatory object.
 //   "invocation": {
-//     // The contents of the $DMD environment variable. A mandatory string.
-//     "dmdEnvVar": "1",
+//     // The contents of the $DMD environment variable. A string, or |null| is
+//     // $DMD is undefined.
+//     "dmdEnvVar": "--mode=dark-matter",
 //
 //     // The profiling mode. A mandatory string taking one of the following
 //     // values: "live", "dark-matter", "cumulative".
 //     "mode": "dark-matter",
 //
 //     // The value of the --sample-below-size option. A mandatory integer.
 //     "sampleBelowSize": 4093
 //   },
--- a/memory/replace/dmd/dmd.py
+++ b/memory/replace/dmd/dmd.py
@@ -15,17 +15,17 @@ import json
 import os
 import platform
 import re
 import shutil
 import sys
 import tempfile
 
 # The DMD output version this script handles.
-outputVersion = 2
+outputVersion = 3
 
 # If --ignore-alloc-fns is specified, stack frames containing functions that
 # match these strings will be removed from the *start* of stack traces. (Once
 # we hit a non-matching frame, any subsequent frames won't be removed even if
 # they do match.)
 allocatorFns = [
     'replace_malloc',
     'replace_calloc',
@@ -610,17 +610,20 @@ def printDigest(args, digest):
                     out('  }')
             out('}\n')
 
         return (kindUsableSize, kindBlocks)
 
 
     def printInvocation(n, dmdEnvVar, sampleBelowSize):
         out('Invocation{:} {{'.format(n))
-        out('  $DMD = \'' + dmdEnvVar + '\'')
+        if dmdEnvVar == None:
+            out('  $DMD is undefined')
+        else:
+            out('  $DMD = \'' + dmdEnvVar + '\'')
         out('  Sample-below size = ' + str(sampleBelowSize))
         out('}\n')
 
     # Print command line. Strip dirs so the output is deterministic, which is
     # needed for testing.
     out(separator, end='')
     out('# ' + ' '.join(map(os.path.basename, sys.argv)) + '\n')
 
--- a/memory/replace/dmd/test/script-diff-dark-matter-expected.txt
+++ b/memory/replace/dmd/test/script-diff-dark-matter-expected.txt
@@ -1,13 +1,13 @@
 #-----------------------------------------------------------------
 # dmd.py --filter-stacks-for-testing -o script-diff-dark-matter-actual.txt script-diff-dark-matter1.json script-diff-dark-matter2.json
 
 Invocation 1 {
-  $DMD = '--sample-below=127'
+  $DMD = '--mode=dark-matter --sample-below=127'
   Sample-below size = 127
 }
 
 Invocation 2 {
   $DMD = '--sample-below=63'
   Sample-below size = 63
 }
 
--- a/memory/replace/dmd/test/script-diff-dark-matter1.json
+++ b/memory/replace/dmd/test/script-diff-dark-matter1.json
@@ -1,12 +1,12 @@
 {
- "version": 2,
+ "version": 3,
  "invocation": {
-  "dmdEnvVar": "--sample-below=127",
+  "dmdEnvVar": "--mode=dark-matter --sample-below=127",
   "mode": "dark-matter",
   "sampleBelowSize": 127
  },
  "blockList": [
   {"req": 4096, "alloc": "A"},
   {"req": 4096, "alloc": "A"},
   {"req": 4096, "alloc": "A"},
   {"req": 4096, "alloc": "A"},
--- a/memory/replace/dmd/test/script-diff-dark-matter2.json
+++ b/memory/replace/dmd/test/script-diff-dark-matter2.json
@@ -1,10 +1,10 @@
 {
- "version": 2,
+ "version": 3,
  "invocation": {
   "dmdEnvVar": "--sample-below=63",
   "mode": "dark-matter",
   "sampleBelowSize": 63
  },
  "blockList": [
   {"req": 4096, "alloc": "A"},
   {"req": 4096, "alloc": "A"},
--- a/memory/replace/dmd/test/script-diff-live-expected.txt
+++ b/memory/replace/dmd/test/script-diff-live-expected.txt
@@ -1,18 +1,18 @@
 #-----------------------------------------------------------------
 # dmd.py --filter-stacks-for-testing -o script-diff-live-actual.txt script-diff-live1.json script-diff-live2.json
 
 Invocation 1 {
-  $DMD = '--sample-below=127'
+  $DMD = '--mode=live --sample-below=127'
   Sample-below size = 127
 }
 
 Invocation 2 {
-  $DMD = '--sample-below=63'
+  $DMD = '--mode=live --sample-below=63'
   Sample-below size = 63
 }
 
 #-----------------------------------------------------------------
 
 Live {
   4 blocks in heap block record 1 of 6
   16,384 bytes (16,384 requested / 0 slop)
--- a/memory/replace/dmd/test/script-diff-live1.json
+++ b/memory/replace/dmd/test/script-diff-live1.json
@@ -1,12 +1,12 @@
 {
- "version": 2,
+ "version": 3,
  "invocation": {
-  "dmdEnvVar": "--sample-below=127",
+  "dmdEnvVar": "--mode=live --sample-below=127",
   "mode": "live",
   "sampleBelowSize": 127
  },
  "blockList": [
   {"req": 4096, "alloc": "A"},
   {"req": 4096, "alloc": "A"},
   {"req": 4096, "alloc": "A"},
   {"req": 4096, "alloc": "A"},
--- a/memory/replace/dmd/test/script-diff-live2.json
+++ b/memory/replace/dmd/test/script-diff-live2.json
@@ -1,12 +1,12 @@
 {
- "version": 2,
+ "version": 3,
  "invocation": {
-  "dmdEnvVar": "--sample-below=63",
+  "dmdEnvVar": "--mode=live --sample-below=63",
   "mode": "live",
   "sampleBelowSize": 63
  },
  "blockList": [
   {"req": 4096, "alloc": "A"},
   {"req": 4096, "alloc": "A"},
   {"req": 4096, "alloc": "A"},
   {"req": 4096, "alloc": "A"},
--- a/memory/replace/dmd/test/script-ignore-alloc-fns-expected.txt
+++ b/memory/replace/dmd/test/script-ignore-alloc-fns-expected.txt
@@ -1,57 +1,72 @@
 #-----------------------------------------------------------------
 # dmd.py --filter-stacks-for-testing -o script-ignore-alloc-fns-actual.txt --ignore-alloc-fns script-ignore-alloc-fns.json
 
 Invocation {
-  $DMD = '1'
+  $DMD is undefined
   Sample-below size = 2500
 }
 
 #-----------------------------------------------------------------
 
-Live {
+# no twice-reported heap blocks
+
+#-----------------------------------------------------------------
+
+Unreported {
   1 block in heap block record 1 of 4
   1,048,576 bytes (1,048,576 requested / 0 slop)
   93.22% of the heap (93.22% cumulative)
+  93.22% of unreported (93.22% cumulative)
   Allocated at {
     #01: A (A.cpp:99)
   }
 }
 
-Live {
+Unreported {
   1 block in heap block record 2 of 4
   65,536 bytes (65,536 requested / 0 slop)
   5.83% of the heap (99.05% cumulative)
+  5.83% of unreported (99.05% cumulative)
   Allocated at {
     #01: js::jit::JitRuntime::initialize(JSContext*) (Ion.cpp:301)
   }
 }
 
-Live {
+Unreported {
   1 block in heap block record 3 of 4
   8,192 bytes (8,000 requested / 192 slop)
   0.73% of the heap (99.78% cumulative)
+  0.73% of unreported (99.78% cumulative)
   Allocated at {
     #01: mozilla::Vector::growStorageBy(unsigned long) (Vector.h:802)
     #02: D (D.cpp:99)
   }
 }
 
-Live {
+Unreported {
   ~1 block in heap block record 4 of 4
   ~2,500 bytes (~2,500 requested / ~0 slop)
   0.22% of the heap (100.00% cumulative)
+  0.22% of unreported (100.00% cumulative)
   Allocated at {
     #01: g_type_create_instance (/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0)
     #02: not_an_alloc_function_so_alloc_functions_below_here_will_not_be_stripped (blah)
     #03: replace_posix_memalign (replace_malloc.h:120)
     #04: ??? (/lib/x86_64-linux-gnu/libglib-2.0.so.0)
     #05: another_non_alloc_function (blah)
   }
 }
 
 #-----------------------------------------------------------------
 
+# no once-reported heap blocks
+
+#-----------------------------------------------------------------
+
 Summary {
-  Total: ~1,124,804 bytes in ~4 blocks
+  Total:            ~1,124,804 bytes (100.00%) in      ~4 blocks (100.00%)
+  Unreported:       ~1,124,804 bytes (100.00%) in      ~4 blocks (100.00%)
+  Once-reported:            ~0 bytes (  0.00%) in      ~0 blocks (  0.00%)
+  Twice-reported:           ~0 bytes (  0.00%) in      ~0 blocks (  0.00%)
 }
 
--- a/memory/replace/dmd/test/script-ignore-alloc-fns.json
+++ b/memory/replace/dmd/test/script-ignore-alloc-fns.json
@@ -1,13 +1,13 @@
 {
- "version": 2,
+ "version": 3,
  "invocation": {
-  "dmdEnvVar": "1",
-  "mode": "live",
+  "dmdEnvVar": null,
+  "mode": "dark-matter",
   "sampleBelowSize": 2500
  },
  "blockList": [
   {"req": 1048576,           "alloc": "A"},
   {"req": 65536,             "alloc": "B"},
   {"req": 8000, "slop": 192, "alloc": "C"},
   {                          "alloc": "D"}
  ],
--- a/memory/replace/dmd/test/script-max-frames-1-expected.txt
+++ b/memory/replace/dmd/test/script-max-frames-1-expected.txt
@@ -1,13 +1,13 @@
 #-----------------------------------------------------------------
 # dmd.py --filter-stacks-for-testing -o script-max-frames-1-actual.txt --max-frames=1 script-max-frames.json
 
 Invocation {
-  $DMD = '1'
+  $DMD = '--mode=live'
   Sample-below size = 1
 }
 
 #-----------------------------------------------------------------
 
 Live {
   4 blocks in heap block record 1 of 1
   4,416 bytes (4,404 requested / 12 slop)
--- a/memory/replace/dmd/test/script-max-frames-3-expected.txt
+++ b/memory/replace/dmd/test/script-max-frames-3-expected.txt
@@ -1,13 +1,13 @@
 #-----------------------------------------------------------------
 # dmd.py --filter-stacks-for-testing -o script-max-frames-3-actual.txt --max-frames=3 --no-fix-stacks script-max-frames.json
 
 Invocation {
-  $DMD = '1'
+  $DMD = '--mode=live'
   Sample-below size = 1
 }
 
 #-----------------------------------------------------------------
 
 Live {
   2 blocks in heap block record 1 of 3
   4,224 bytes (4,224 requested / 0 slop)
--- a/memory/replace/dmd/test/script-max-frames-8-expected.txt
+++ b/memory/replace/dmd/test/script-max-frames-8-expected.txt
@@ -1,13 +1,13 @@
 #-----------------------------------------------------------------
 # dmd.py --filter-stacks-for-testing -o script-max-frames-8-actual.txt --max-frames=8 script-max-frames.json
 
 Invocation {
-  $DMD = '1'
+  $DMD = '--mode=live'
   Sample-below size = 1
 }
 
 #-----------------------------------------------------------------
 
 Live {
   1 block in heap block record 1 of 4
   4,096 bytes (4,096 requested / 0 slop)
--- a/memory/replace/dmd/test/script-max-frames.json
+++ b/memory/replace/dmd/test/script-max-frames.json
@@ -1,12 +1,12 @@
 {
- "version": 2,
+ "version": 3,
  "invocation": {
-  "dmdEnvVar": "1",
+  "dmdEnvVar": "--mode=live",
   "mode": "live",
   "sampleBelowSize": 1
  },
  "blockList": [
   {"req": 4096, "alloc": "A"},
   {"req": 128, "alloc": "B"},
   {"req": 100, "slop":12, "alloc": "C"},
   {"req": 80, "alloc": "D"}
--- a/memory/replace/dmd/test/script-sort-by-req-expected.txt
+++ b/memory/replace/dmd/test/script-sort-by-req-expected.txt
@@ -1,13 +1,13 @@
 #-----------------------------------------------------------------
 # dmd.py --filter-stacks-for-testing -o script-sort-by-req-actual.txt --sort-by=req --no-fix-stacks script-sort-by.json.gz
 
 Invocation {
-  $DMD = '1'
+  $DMD = '--mode=live'
   Sample-below size = 1
 }
 
 #-----------------------------------------------------------------
 
 Live {
   5 blocks in heap block record 1 of 3
   16,392 bytes (16,392 requested / 0 slop)
--- a/memory/replace/dmd/test/script-sort-by-slop-expected.txt
+++ b/memory/replace/dmd/test/script-sort-by-slop-expected.txt
@@ -1,13 +1,13 @@
 #-----------------------------------------------------------------
 # dmd.py --filter-stacks-for-testing -o script-sort-by-slop-actual.txt --sort-by=slop script-sort-by.json.gz
 
 Invocation {
-  $DMD = '1'
+  $DMD = '--mode=live'
   Sample-below size = 1
 }
 
 #-----------------------------------------------------------------
 
 Live {
   4 blocks in heap block record 1 of 3
   16,384 bytes (8,196 requested / 8,188 slop)
--- a/memory/replace/dmd/test/script-sort-by-usable-expected.txt
+++ b/memory/replace/dmd/test/script-sort-by-usable-expected.txt
@@ -1,13 +1,13 @@
 #-----------------------------------------------------------------
 # dmd.py --filter-stacks-for-testing -o script-sort-by-usable-actual.txt --sort-by=usable script-sort-by.json.gz
 
 Invocation {
-  $DMD = '1'
+  $DMD = '--mode=live'
   Sample-below size = 1
 }
 
 #-----------------------------------------------------------------
 
 Live {
   5 blocks in heap block record 1 of 3
   16,400 bytes (12,016 requested / 4,384 slop)
index fb767c74adca6ee27c176fea47d23aff1e65ef89..6a68f955dcb54deb8196208823b61cecca05b7d9
GIT binary patch
literal 302
zc$@()0nz>+iwFpE$cIz_19M|?X>fEcb8m8VEn;~tYIARH0L_v?PlPZKh41|plktKH
zYr5`c6%r3^<IS7Ki{a3Pnh*;`Aecz@zuRF~7We_HJ@w7^`kF~z&j349H@Pb@hE3>Y
zUUn|k?QzmG0L+T)vFu)T?FYD86)rOmHt!6EL`f1jPa0iR)<|RB*K__&aLwRA*?a5K
zkEgt8{p`(Kd#uf;zi)Z83jwwDoU#Ox{WADI1b-HI!Z)0A|GcrTqD>ZIavt_i%<J8-
z)a)$G6Zb9OM(1d+?xxXd9{q=A1__m@t#xW%^xm4^f(oh=3W3ScKRHM#Pf`t1DNIf+
ze6Mw}2%rSK;yeZcfw)PlDvqM-W1XcOp@cxrp;9AM5U3IQuh@b809RSp{$B$C0KtKg
A82|tP
--- a/memory/replace/dmd/test/test_dmd.js
+++ b/memory/replace/dmd/test/test_dmd.js
@@ -118,17 +118,16 @@ function run_test() {
 
   // These tests do full end-to-end testing of DMD, i.e. both the C++ code that
   // generates the JSON output, and the script that post-processes that output.
   //
   // Run these synchronously, because test() updates the full*.json files
   // in-place (to fix stacks) when it runs dmd.py, and that's not safe to do
   // asynchronously.
 
-  gEnv.set("DMD", "1");
   gEnv.set(gEnv.get("DMD_PRELOAD_VAR"), gEnv.get("DMD_PRELOAD_VALUE"));
 
   runProcess(gDmdTestFile, []);
 
   function test2(aTestName, aMode) {
     let name = "full-" + aTestName + "-" + aMode;
     jsonFile = FileUtils.getFile("CurWorkD", [name + ".json"]);
     test(name, [jsonFile.path]);
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -973,44 +973,40 @@ class RunProgram(MachCommandBase):
                 dmd_params.append('--mode=' + mode)
             if sample_below:
                 dmd_params.append('--sample-below=' + sample_below)
             if max_frames:
                 dmd_params.append('--max-frames=' + max_frames)
             if show_dump_stats:
                 dmd_params.append('--show-dump-stats=yes')
 
+            env_vars = {
+                "Darwin": {
+                    "DYLD_INSERT_LIBRARIES": dmd_lib,
+                    "LD_LIBRARY_PATH": bin_dir,
+                },
+                "Linux": {
+                    "LD_PRELOAD": dmd_lib,
+                    "LD_LIBRARY_PATH": bin_dir,
+                },
+                "WINNT": {
+                    "MOZ_REPLACE_MALLOC_LIB": dmd_lib,
+                },
+            }
+
             if dmd_params:
-                dmd_env_var = " ".join(dmd_params)
-            else:
-                dmd_env_var = "1"
+                env_vars["DMD"] = " ".join(dmd_params)
 
             bin_dir = os.path.dirname(binpath)
             lib_name = self.substs['DLL_PREFIX'] + 'dmd' + self.substs['DLL_SUFFIX']
             dmd_lib = os.path.join(bin_dir, lib_name)
             if not os.path.exists(dmd_lib):
                 print("Please build with |--enable-dmd| to use DMD.")
                 return 1
 
-            env_vars = {
-                "Darwin": {
-                    "DYLD_INSERT_LIBRARIES": dmd_lib,
-                    "LD_LIBRARY_PATH": bin_dir,
-                    "DMD": dmd_env_var,
-                },
-                "Linux": {
-                    "LD_PRELOAD": dmd_lib,
-                    "LD_LIBRARY_PATH": bin_dir,
-                    "DMD": dmd_env_var,
-                },
-                "WINNT": {
-                    "MOZ_REPLACE_MALLOC_LIB": dmd_lib,
-                    "DMD": dmd_env_var,
-                },
-            }
             extra_env.update(env_vars.get(self.substs['OS_ARCH'], {}))
 
         return self.run_process(args=args, ensure_exit_code=False,
             pass_thru=True, append_env=extra_env)
 
 @CommandProvider
 class Buildsymbols(MachCommandBase):
     """Produce a package of debug symbols suitable for use with Breakpad."""