summaryrefslogtreecommitdiffstats
path: root/skia
diff options
context:
space:
mode:
authorcpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-06 04:07:04 +0000
committercpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-06 04:07:04 +0000
commit2caf79aeec7d705b87b071344f1cc48c33946075 (patch)
treed5a8a8d7c64427777b45dab56259417d8f1f8202 /skia
parent4b8d4493866c2826c66cf6011dadeafea6eda42a (diff)
downloadchromium_src-2caf79aeec7d705b87b071344f1cc48c33946075.zip
chromium_src-2caf79aeec7d705b87b071344f1cc48c33946075.tar.gz
chromium_src-2caf79aeec7d705b87b071344f1cc48c33946075.tar.bz2
Beef up and reenable memory diagnostics for skia canvas
We got a big crash spike in canary. See bug below. BUG=7913 TEST=see bug Review URL: http://codereview.chromium.org/9112026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@116646 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia')
-rw-r--r--skia/ext/platform_canvas_win.cc77
1 files changed, 38 insertions, 39 deletions
diff --git a/skia/ext/platform_canvas_win.cc b/skia/ext/platform_canvas_win.cc
index f2b993b..371de78 100644
--- a/skia/ext/platform_canvas_win.cc
+++ b/skia/ext/platform_canvas_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,11 +14,11 @@ namespace skia {
// Disable optimizations during crash analysis.
#pragma optimize("", off)
-// Crash on failure.
-#define CHECK(condition) if (!(condition)) __debugbreak();
+// Crash On Failure. |address| should be a number less than 4000.
+#define COF(address, condition) if (!(condition)) *((int*) address) = 0
-// Crashes the process. This is called when a bitmap allocation fails, and this
-// function tries to determine why it might have failed, and crash on different
+// This is called when a bitmap allocation fails, and this function tries to
+// determine why it might have failed, and crash on different
// lines. This allows us to see in crash dumps the most likely reason for the
// failure. It takes the size of the bitmap we were trying to allocate as its
// arguments so we can check that as well.
@@ -26,20 +26,13 @@ namespace skia {
// Note that in a sandboxed renderer this function crashes when trying to
// call GetProcessMemoryInfo() because it tries to load psapi.dll, which
// is fine but gives you a very hard to read crash dump.
-void CrashForBitmapAllocationFailure(int w, int h) {
+void CrashForBitmapAllocationFailure(int w, int h, unsigned int error) {
// Store the extended error info in a place easy to find at debug time.
- struct {
- unsigned int last_error;
- unsigned int diag_error;
- } extended_error_info;
- extended_error_info.last_error = GetLastError();
- extended_error_info.diag_error = 0;
-
+ unsigned int diag_error = 0;
// If the bitmap is ginormous, then we probably can't allocate it.
- // We use 64M pixels = 256MB @ 4 bytes per pixel.
- const __int64 kGinormousBitmapPxl = 64000000;
- CHECK(static_cast<__int64>(w) * static_cast<__int64>(h) <
- kGinormousBitmapPxl);
+ // We use 32M pixels = 128MB @ 4 bytes per pixel.
+ const LONG_PTR kGinormousBitmapPxl = 32000000;
+ COF(1, LONG_PTR(w) * LONG_PTR(h) < kGinormousBitmapPxl);
// The maximum number of GDI objects per process is 10K. If we're very close
// to that, it's probably the problem.
@@ -47,23 +40,26 @@ void CrashForBitmapAllocationFailure(int w, int h) {
unsigned int num_gdi_objects = GetGuiResources(GetCurrentProcess(),
GR_GDIOBJECTS);
if (num_gdi_objects == 0) {
- extended_error_info.diag_error = GetLastError();
- CHECK(0);
+ diag_error = GetLastError();
+ COF(2, false);
}
- CHECK(num_gdi_objects < kLotsOfGDIObjects);
+ COF(3, num_gdi_objects < kLotsOfGDIObjects);
// If we're using a crazy amount of virtual address space, then maybe there
// isn't enough for our bitmap.
const SIZE_T kLotsOfMem = 1500000000; // 1.5GB.
- PROCESS_MEMORY_COUNTERS pmc;
- if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
- extended_error_info.diag_error = GetLastError();
- CHECK(0);
+ PROCESS_MEMORY_COUNTERS_EX pmc;
+ pmc.cb = sizeof(pmc);
+ if (!GetProcessMemoryInfo(GetCurrentProcess(),
+ reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&pmc),
+ sizeof(pmc))) {
+ diag_error = GetLastError();
+ COF(4, false);
}
- CHECK(pmc.PagefileUsage < kLotsOfMem);
-
- // Everything else.
- CHECK(0);
+ COF(5, pmc.PagefileUsage < kLotsOfMem);
+ COF(6, pmc.PrivateUsage < kLotsOfMem);
+ // Ok but we are somehow out of memory?
+ COF(7, error != ERROR_NOT_ENOUGH_MEMORY);
}
// Crashes the process. This is called when a bitmap allocation fails but
@@ -71,7 +67,7 @@ void CrashForBitmapAllocationFailure(int w, int h) {
// the issue was a non-valid shared bitmap handle.
void CrashIfInvalidSection(HANDLE shared_section) {
DWORD handle_info = 0;
- CHECK(::GetHandleInformation(shared_section, &handle_info) == TRUE);
+ COF(8, ::GetHandleInformation(shared_section, &handle_info) == TRUE);
}
// Restore the optimization options.
@@ -80,9 +76,7 @@ void CrashIfInvalidSection(HANDLE shared_section) {
PlatformCanvas::PlatformCanvas(int width, int height, bool is_opaque) {
TRACE_EVENT2("skia", "PlatformCanvas::PlatformCanvas",
"width", width, "height", height);
- bool initialized = initialize(width, height, is_opaque, NULL);
- if (!initialized)
- CrashForBitmapAllocationFailure(width, height);
+ initialize(width, height, is_opaque, NULL);
}
PlatformCanvas::PlatformCanvas(int width,
@@ -91,11 +85,7 @@ PlatformCanvas::PlatformCanvas(int width,
HANDLE shared_section) {
TRACE_EVENT2("skia", "PlatformCanvas::PlatformCanvas",
"width", width, "height", height);
- bool initialized = initialize(width, height, is_opaque, shared_section);
- if (!initialized) {
- CrashIfInvalidSection(shared_section);
- CrashForBitmapAllocationFailure(width, height);
- }
+ initialize(width, height, is_opaque, shared_section);
}
PlatformCanvas::~PlatformCanvas() {
@@ -105,8 +95,17 @@ bool PlatformCanvas::initialize(int width,
int height,
bool is_opaque,
HANDLE shared_section) {
- return initializeWithDevice(BitmapPlatformDevice::create(
- width, height, is_opaque, shared_section));
+ if (initializeWithDevice(BitmapPlatformDevice::create(width,
+ height,
+ is_opaque,
+ shared_section)))
+ return true;
+ // Investigate we failed. If we know the reason, crash in a specific place.
+ unsigned int error = GetLastError();
+ if (shared_section)
+ CrashIfInvalidSection(shared_section);
+ CrashForBitmapAllocationFailure(width, height, error);
+ return false;
}
} // namespace skia