diff options
author | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-06 04:07:04 +0000 |
---|---|---|
committer | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-06 04:07:04 +0000 |
commit | 2caf79aeec7d705b87b071344f1cc48c33946075 (patch) | |
tree | d5a8a8d7c64427777b45dab56259417d8f1f8202 /skia | |
parent | 4b8d4493866c2826c66cf6011dadeafea6eda42a (diff) | |
download | chromium_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.cc | 77 |
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 |