mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-06-12 03:18:57 +00:00
696c195395
- Bug 1161686 - libmar's |SECU_GetModulePassword| can leak allocated string (command line build utility). Free unused return of GetPasswordString. r=bbondy (25107e4c3e)
- Bug 1253775 - Remove libmar and libbz2 Makefile.ins; r=ted (7d693933b8)
- Bug 1186934 - update jemalloc to upstream HEAD; r=glandium (cd4fdf0c93)
- Bug 1254850 - Update jemalloc 4 to version 4.1.0. r=njn (6cc351fb51)
- Bug 1254948 - Remove makefiles used to transition from jemalloc_config.c to jemalloc_config.cpp; r=glandium (c8e0684478)
- Bug 1263735: Update libcubeb to remove wasapi stubbing for enumeration r=kinetik (156c7e4ef8)
- Bug 1264594 - Update libcubeb to revision 727121. r=kinetik (e982bc0eef)
- Bug 1264892: Use system declaration of |__system_property_get| on B2G, r=padenot (b50185e037)
- Bug 1265692 - Update cubeb to 0bc02f9. r=padenot,kinetik (420c905a02)
- Bug 1251502 - Add a duplex AudioUnit implementation. r=kinetik,padenot (a4e00f217a)
- Bug 1266753 - Update cubeb to revision dbdfb to pick up OSX device notification changes. r=padenot (12532f1cf6)
- Bug 1266753 - Fix mac bustage: use the old enum values, on a CLOSED TREE. r=padenot (afe9874670)
- Bug 1251502 - Compile the resampling code in cubeb for OSX and Linux. r=kinetik (6f07d50796)
- Bug 1236937 - Use correct value for Pi in AAFilter.cpp. r=padenot (d54113bf18)
- Bug 1235675 - Add the source directory to the -include directive in media/libsoundtouch/src/moz.build. r=mshal (0d56029898)
- Bug 1135942 - Enable MMX/SSE code unconditionally in libsoundtouch, it does runtime detection anyways. r=padenot (1e1c3c6c84)
- Bug 1134744 - Fix baseline for form controls when line is inverted relative to block dir. r=smontagu (8be618ce3f)
- Bug 1261284: Don't include <button>'s children in overflow areas, if we know we're going to clip them when painting. r=mats (094dd9c33b)
- Bug 1263773 - Mark a bunch of classes in layout as MOZ_RAII. r=dholbert (e28d735a60)
- Bug 1249664 - Save the combobox's dropped-down state across frame reconstruction. r=dbaron (6caf06c91e)
- Bug 1253977 part 1 - Update focus state on combobox frame destruction/construction properly. r=tn (0c1841dc35)
- Bug 1253977 part 2 - Reftests. (985b87a008)
- Bug 1212688 - Drill through any <optgroup> scroll frames to get at its <option> child frames when estimating the list's row size. r=roc (67b9ac481c)
- Bug 1228670 - Null-check GetContentInsertionFrame() before using it. r=bz (bffbf4769c)
- Bug 1208978 - Limit the size of a potentially-scrollable dropdown list to the actual size of its contents, as our estimate based on row count may be too large if the row heights vary. r=roc (b9447f9f1c)
- Bug 1121515 - Error tapping empty listitem in a <select> box, r=roc, wesj (bffe267a89)
- Bug 1194733 - Don't honor DefaultPrevented for mouseup events in list control frames. r=enndeakin@gmail.com (37c43372b6)
- bits of 1225280 (1869476ed8)
- Bug 1239504 - Avoid ASan leak report by holding PseudoStack in ImageBridgeChild. r=sotaro (d9125680ad)
- Bug 1223193: P1. Make ImageBridgeChild::mShuttingDown atomic. r=nical (3a5b496dae)
- Bug 1223193: P2. Cancel ImageBridge proxy functions if shutdown has started. r=nical (a66cd45878)
- Bug 1243466 - Don't crash if DeallocPImageContainerChild is called prematurely. r=sotaro (e8d4776fde)
- Bug 1251808 (Followup) - Mark the new SourceSurfaceImage constructor explicit. r=me (1087add7d0)
- Bug 1260391: Fix |ImageBridgeChild::UseOverlaySource|, r=dvander (e423cc3a27)
- Bug 1255823 - Add a two-step destruction process to PAPZ. r=dvander (3d53adaecc)
- Bug 1261321 - Null-check when the CompositableClient when forcing its destruction at shutdown. r=jnicol (7180c6d737)
- Bug 1259301 - Remove GeckoContentController::RequestFlingSnap(). r=kats (d94da5f624)
- Bug 1253512 (part 1) - Overhaul DMD's "sampling". r=erahm. (536dcdf84e)
- Bug 1282185 (part 1) - Remove a bogus assertion in DMD. r=erahm. (ec09953fac)
- Bug 1253512 (part 2) - Aggregate live blocks. r=erahm. (57db2ffa75)
- Bug 1254029 - Do not wait in ImageBridgeChild::FlushAllImages() except gonk r=nical (aeac940199)
- Bug 1175895 - separate tier start message for mach; r=ted (cd56ddae05)
- Bug 1077670 - Package tests in parallel. r=gps (28b531ba3d)
- Bug 1253478 - Use Atomic<uint64_t> in AsyncTransactionTracker r=nical (c1f2cf892f)
- Bug 1150338 - Use the tooltool gcc in automation rather than /tools, r=terrence (15f1fa12bc)
- Bug 1259848 - Various fixes for finding gcc in the correct location for spidermonkey TC builds and hazard shell builds, r=terrence (9963274899)
380 lines
9.8 KiB
C++
380 lines
9.8 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* 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/. */
|
|
|
|
// This program is used by the DMD xpcshell test. It is run under DMD and
|
|
// produces some output. The xpcshell test then post-processes and checks this
|
|
// output.
|
|
//
|
|
// Note that this file does not have "Test" or "test" in its name, because that
|
|
// will cause the build system to not record breakpad symbols for it, which
|
|
// will stop the post-processing (which includes stack fixing) from working
|
|
// correctly.
|
|
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "mozilla/Assertions.h"
|
|
#include "mozilla/JSONWriter.h"
|
|
#include "mozilla/UniquePtr.h"
|
|
#include "DMD.h"
|
|
|
|
using mozilla::JSONWriter;
|
|
using mozilla::MakeUnique;
|
|
using namespace mozilla::dmd;
|
|
|
|
DMDFuncs::Singleton DMDFuncs::sSingleton;
|
|
|
|
class FpWriteFunc : public mozilla::JSONWriteFunc
|
|
{
|
|
public:
|
|
explicit FpWriteFunc(const char* aFilename)
|
|
{
|
|
mFp = fopen(aFilename, "w");
|
|
if (!mFp) {
|
|
fprintf(stderr, "SmokeDMD: can't create %s file: %s\n",
|
|
aFilename, strerror(errno));
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
~FpWriteFunc() { fclose(mFp); }
|
|
|
|
void Write(const char* aStr) { fputs(aStr, mFp); }
|
|
|
|
private:
|
|
FILE* mFp;
|
|
};
|
|
|
|
// This stops otherwise-unused variables from being optimized away.
|
|
static void
|
|
UseItOrLoseIt(void* aPtr, int aSeven)
|
|
{
|
|
char buf[64];
|
|
int n = sprintf(buf, "%p\n", aPtr);
|
|
if (n == 20 + aSeven) {
|
|
fprintf(stderr, "well, that is surprising");
|
|
}
|
|
}
|
|
|
|
// This function checks that heap blocks that have the same stack trace but
|
|
// different (or no) reporters get aggregated separately.
|
|
void Foo(int aSeven)
|
|
{
|
|
char* a[6];
|
|
for (int i = 0; i < aSeven - 1; i++) {
|
|
a[i] = (char*) malloc(128 - 16*i);
|
|
}
|
|
|
|
// Oddly, some versions of clang will cause identical stack traces to be
|
|
// generated for adjacent calls to Report(), which breaks the test. Inserting
|
|
// the UseItOrLoseIt() calls in between is enough to prevent this.
|
|
|
|
Report(a[2]); // reported
|
|
|
|
UseItOrLoseIt(a[2], aSeven);
|
|
|
|
for (int i = 0; i < aSeven - 5; i++) {
|
|
Report(a[i]); // reported
|
|
}
|
|
|
|
UseItOrLoseIt(a[2], aSeven);
|
|
|
|
Report(a[3]); // reported
|
|
|
|
// a[4], a[5] unreported
|
|
}
|
|
|
|
void
|
|
TestEmpty(const char* aTestName, const char* aMode)
|
|
{
|
|
char filename[128];
|
|
sprintf(filename, "complete-%s-%s.json", aTestName, aMode);
|
|
auto f = MakeUnique<FpWriteFunc>(filename);
|
|
|
|
char options[128];
|
|
sprintf(options, "--mode=%s --stacks=full", aMode);
|
|
ResetEverything(options);
|
|
|
|
// Zero for everything.
|
|
Analyze(Move(f));
|
|
}
|
|
|
|
void
|
|
TestFull(const char* aTestName, int aNum, const char* aMode, int aSeven)
|
|
{
|
|
char filename[128];
|
|
sprintf(filename, "complete-%s%d-%s.json", aTestName, aNum, aMode);
|
|
auto f = MakeUnique<FpWriteFunc>(filename);
|
|
|
|
// The --show-dump-stats=yes is there just to give that option some basic
|
|
// testing, e.g. ensure it doesn't crash. It's hard to test much beyond that.
|
|
char options[128];
|
|
sprintf(options, "--mode=%s --stacks=full --show-dump-stats=yes", aMode);
|
|
ResetEverything(options);
|
|
|
|
// Analyze 1: 1 freed, 9 out of 10 unreported.
|
|
// Analyze 2: still present and unreported.
|
|
int i;
|
|
char* a = nullptr;
|
|
for (i = 0; i < aSeven + 3; i++) {
|
|
a = (char*) malloc(100);
|
|
UseItOrLoseIt(a, aSeven);
|
|
}
|
|
free(a);
|
|
|
|
// A no-op.
|
|
free(nullptr);
|
|
|
|
// Note: 8 bytes is the smallest requested size that gives consistent
|
|
// behaviour across all platforms with jemalloc.
|
|
// Analyze 1: reported.
|
|
// Analyze 2: thrice-reported.
|
|
char* a2 = (char*) malloc(8);
|
|
Report(a2);
|
|
|
|
// Analyze 1: reported.
|
|
// Analyze 2: reportedness carries over, due to ReportOnAlloc.
|
|
char* b = (char*) malloc(10);
|
|
ReportOnAlloc(b);
|
|
|
|
// ReportOnAlloc, then freed.
|
|
// Analyze 1: freed, irrelevant.
|
|
// Analyze 2: freed, irrelevant.
|
|
char* b2 = (char*) malloc(8);
|
|
ReportOnAlloc(b2);
|
|
free(b2);
|
|
|
|
// Analyze 1: reported 4 times.
|
|
// Analyze 2: freed, irrelevant.
|
|
char* c = (char*) calloc(10, 3);
|
|
Report(c);
|
|
for (int i = 0; i < aSeven - 4; i++) {
|
|
Report(c);
|
|
}
|
|
|
|
// Analyze 1: ignored.
|
|
// Analyze 2: irrelevant.
|
|
Report((void*)(intptr_t)i);
|
|
|
|
// jemalloc rounds this up to 8192.
|
|
// Analyze 1: reported.
|
|
// Analyze 2: freed.
|
|
char* e = (char*) malloc(4096);
|
|
e = (char*) realloc(e, 7169);
|
|
Report(e);
|
|
|
|
// First realloc is like malloc; second realloc is shrinking.
|
|
// Analyze 1: reported.
|
|
// Analyze 2: re-reported.
|
|
char* e2 = (char*) realloc(nullptr, 1024);
|
|
e2 = (char*) realloc(e2, 512);
|
|
Report(e2);
|
|
|
|
// First realloc is like malloc; second realloc creates a min-sized block.
|
|
// XXX: on Windows, second realloc frees the block.
|
|
// Analyze 1: reported.
|
|
// Analyze 2: freed, irrelevant.
|
|
char* e3 = (char*) realloc(nullptr, 1023);
|
|
//e3 = (char*) realloc(e3, 0);
|
|
MOZ_ASSERT(e3);
|
|
Report(e3);
|
|
|
|
// Analyze 1: freed, irrelevant.
|
|
// Analyze 2: freed, irrelevant.
|
|
char* f1 = (char*) malloc(64);
|
|
free(f1);
|
|
|
|
// Analyze 1: ignored.
|
|
// Analyze 2: irrelevant.
|
|
Report((void*)(intptr_t)0x0);
|
|
|
|
// Analyze 1: mixture of reported and unreported.
|
|
// Analyze 2: all unreported.
|
|
Foo(aSeven);
|
|
|
|
// Analyze 1: twice-reported.
|
|
// Analyze 2: twice-reported.
|
|
char* g1 = (char*) malloc(77);
|
|
ReportOnAlloc(g1);
|
|
ReportOnAlloc(g1);
|
|
|
|
// Analyze 1: mixture of reported and unreported.
|
|
// Analyze 2: all unreported.
|
|
// Nb: this Foo() call is deliberately not adjacent to the previous one. See
|
|
// the comment about adjacent calls in Foo() for more details.
|
|
Foo(aSeven);
|
|
|
|
// Analyze 1: twice-reported.
|
|
// Analyze 2: once-reported.
|
|
char* g2 = (char*) malloc(78);
|
|
Report(g2);
|
|
ReportOnAlloc(g2);
|
|
|
|
// Analyze 1: twice-reported.
|
|
// Analyze 2: once-reported.
|
|
char* g3 = (char*) malloc(79);
|
|
ReportOnAlloc(g3);
|
|
Report(g3);
|
|
|
|
// All the odd-ball ones.
|
|
// Analyze 1: all unreported.
|
|
// Analyze 2: all freed, irrelevant.
|
|
// XXX: no memalign on Mac
|
|
//void* w = memalign(64, 65); // rounds up to 128
|
|
//UseItOrLoseIt(w, aSeven);
|
|
|
|
// XXX: posix_memalign doesn't work on B2G
|
|
//void* x;
|
|
//posix_memalign(&y, 128, 129); // rounds up to 256
|
|
//UseItOrLoseIt(x, aSeven);
|
|
|
|
// XXX: valloc doesn't work on Windows.
|
|
//void* y = valloc(1); // rounds up to 4096
|
|
//UseItOrLoseIt(y, aSeven);
|
|
|
|
// XXX: C11 only
|
|
//void* z = aligned_alloc(64, 256);
|
|
//UseItOrLoseIt(z, aSeven);
|
|
|
|
if (aNum == 1) {
|
|
// Analyze 1.
|
|
Analyze(Move(f));
|
|
}
|
|
|
|
ClearReports();
|
|
|
|
//---------
|
|
|
|
Report(a2);
|
|
Report(a2);
|
|
free(c);
|
|
free(e);
|
|
Report(e2);
|
|
free(e3);
|
|
//free(w);
|
|
//free(x);
|
|
//free(y);
|
|
//free(z);
|
|
|
|
// Do some allocations that will only show up in cumulative mode.
|
|
for (int i = 0; i < 100; i++) {
|
|
free(malloc(128));
|
|
}
|
|
|
|
if (aNum == 2) {
|
|
// Analyze 2.
|
|
Analyze(Move(f));
|
|
}
|
|
}
|
|
|
|
void
|
|
TestPartial(const char* aTestName, const char* aMode, int aSeven)
|
|
{
|
|
char filename[128];
|
|
sprintf(filename, "complete-%s-%s.json", aTestName, aMode);
|
|
auto f = MakeUnique<FpWriteFunc>(filename);
|
|
|
|
char options[128];
|
|
sprintf(options, "--mode=%s", aMode);
|
|
ResetEverything(options);
|
|
|
|
int kTenThousand = aSeven + 9993;
|
|
char* s;
|
|
|
|
// The output of this function is deterministic but it relies on the
|
|
// probability and seeds given to the FastBernoulliTrial instance in
|
|
// ResetBernoulli(). If they change, the output will change too.
|
|
|
|
// Expected fraction with stacks: (1 - (1 - 0.003) ** 8) = 0.0237
|
|
// So we expect about 0.0237 * 10000 == 237.
|
|
// We actually get 258.
|
|
for (int i = 0; i < kTenThousand; i++) {
|
|
s = (char*) malloc(8);
|
|
UseItOrLoseIt(s, aSeven);
|
|
}
|
|
|
|
// Expected fraction with stacks: (1 - (1 - 0.003) ** 128) = 0.3193,
|
|
// So we expect about 0.3193 * 10000 == 3193.
|
|
// We actually get 3150.
|
|
for (int i = 0; i < kTenThousand; i++) {
|
|
s = (char*) malloc(128);
|
|
UseItOrLoseIt(s, aSeven);
|
|
}
|
|
|
|
// Expected fraction with stacks: (1 - (1 - 0.003) ** 1024) = 0.9539,
|
|
// So we expect about 0.9539 * 10000 == 9539.
|
|
// We actually get 9539.
|
|
for (int i = 0; i < kTenThousand; i++) {
|
|
s = (char*) malloc(1024);
|
|
UseItOrLoseIt(s, aSeven);
|
|
}
|
|
|
|
Analyze(Move(f));
|
|
}
|
|
|
|
void
|
|
TestScan(int aSeven)
|
|
{
|
|
auto f = MakeUnique<FpWriteFunc>("basic-scan.json");
|
|
|
|
ResetEverything("--mode=scan");
|
|
|
|
uintptr_t* p = (uintptr_t*) malloc(6 * sizeof(uintptr_t*));
|
|
UseItOrLoseIt(p, aSeven);
|
|
|
|
// Hard-coded values checked by scan-test.py
|
|
p[0] = 0x123; // outside a block, small value
|
|
p[1] = 0x0; // null
|
|
p[2] = (uintptr_t)((uint8_t*)p - 1); // pointer outside a block, but nearby
|
|
p[3] = (uintptr_t)p; // pointer to start of a block
|
|
p[4] = (uintptr_t)((uint8_t*)p + 1); // pointer into a block
|
|
p[5] = 0x0; // trailing null
|
|
|
|
Analyze(Move(f));
|
|
}
|
|
|
|
void
|
|
RunTests()
|
|
{
|
|
// This test relies on the compiler not doing various optimizations, such as
|
|
// eliding unused malloc() calls or unrolling loops with fixed iteration
|
|
// counts. So we compile it with -O0 (or equivalent), which probably prevents
|
|
// that. We also use the following variable for various loop iteration
|
|
// counts, just in case compilers might unroll very small loops even with
|
|
// -O0.
|
|
int seven = 7;
|
|
|
|
// Make sure that DMD is actually running; it is initialized on the first
|
|
// allocation.
|
|
int *x = (int*)malloc(100);
|
|
UseItOrLoseIt(x, seven);
|
|
MOZ_RELEASE_ASSERT(IsRunning());
|
|
|
|
// Please keep this in sync with run_test in test_dmd.js.
|
|
|
|
TestEmpty("empty", "live");
|
|
TestEmpty("empty", "dark-matter");
|
|
TestEmpty("empty", "cumulative");
|
|
|
|
TestFull("full", 1, "live", seven);
|
|
TestFull("full", 1, "dark-matter", seven);
|
|
|
|
TestFull("full", 2, "dark-matter", seven);
|
|
TestFull("full", 2, "cumulative", seven);
|
|
|
|
TestPartial("partial", "live", seven);
|
|
|
|
TestScan(seven);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
RunTests();
|
|
|
|
return 0;
|
|
}
|