diff options
author | twiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-10 18:31:20 +0000 |
---|---|---|
committer | twiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-10 18:31:20 +0000 |
commit | d9f90a8f48b135757bd5154ba568ab68039ca8f0 (patch) | |
tree | 6c5dad636b244b0b5e50b7b0e828fccff850744f /skia | |
parent | 1a4d71e7c54f810961d2e7463e928f28bc5e4c27 (diff) | |
download | chromium_src-d9f90a8f48b135757bd5154ba568ab68039ca8f0.zip chromium_src-d9f90a8f48b135757bd5154ba568ab68039ca8f0.tar.gz chromium_src-d9f90a8f48b135757bd5154ba568ab68039ca8f0.tar.bz2 |
Re-introduction of release mode checks to determine the cause of CreateDIBSection failures.
The crash is happening outside of the expected conditions in which CreateDIBSection would fail (large bitmap size, GDI and virtual memory pressure). To track the cause, this CL attempts to capture the last system error on bitmap allocation failure.
See previous checks here: http://codereview.chromium.org/8341090
BUG=101934
TEST=NONE
Review URL: http://codereview.chromium.org/8509030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@109461 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia')
-rw-r--r-- | skia/ext/bitmap_platform_device_win.cc | 57 | ||||
-rw-r--r-- | skia/ext/canvas_paint_win.h | 5 |
2 files changed, 58 insertions, 4 deletions
diff --git a/skia/ext/bitmap_platform_device_win.cc b/skia/ext/bitmap_platform_device_win.cc index 3a2a5b4..b655810 100644 --- a/skia/ext/bitmap_platform_device_win.cc +++ b/skia/ext/bitmap_platform_device_win.cc @@ -7,12 +7,64 @@ #include "skia/ext/bitmap_platform_device_win.h" +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/process_util.h" #include "skia/ext/bitmap_platform_device_data.h" #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkRegion.h" #include "third_party/skia/include/core/SkUtils.h" +namespace { +// 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 +// 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. +// Bitmap allocation failures are occuring under conditions outside of GDI and +// address space pressure, so we only crash when resources are not low. +void CrashForBitmapAllocationFailure(int w, int h) { + + DWORD last_error = GetLastError(); + + // The maximum number of GDI objects per process is 10K. If we're very close + // to that, it's probably the problem. + const int kLotsOfGDIObjs = 9990; + if (GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS) > kLotsOfGDIObjs) + return; + + // If the bitmap is ginormous, then we probably can't allocate it. + // We use 64M pixels. + const int64 kGinormousBitmapPxl = 64000000; + if (static_cast<int64>(w) * static_cast<int64>(h) > kGinormousBitmapPxl) + return; + + // If we're using a crazy amount of virtual address space, then maybe there + // isn't enough for our bitmap. + const int64 kLotsOfMem = 1500000000; // 1.5GB. + scoped_ptr<base::ProcessMetrics> process_metrics( + base::ProcessMetrics::CreateProcessMetrics(GetCurrentProcess())); + if (process_metrics->GetPagefileUsage() > kLotsOfMem) + return; + + LPVOID lpMsgBuf = NULL; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + last_error, + 0, + reinterpret_cast<LPTSTR>(&lpMsgBuf), + 0, + NULL); + + CHECK(NO_ERROR == last_error); + LocalFree(lpMsgBuf); +} + +} + namespace skia { BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData( @@ -117,11 +169,16 @@ BitmapPlatformDevice* BitmapPlatformDevice::create( hdr.biClrImportant = 0; void* data = NULL; + + // Force the last error to success so that we can accurately track failures + // in CrashForBitmapAllocationFailure. + SetLastError(ERROR_SUCCESS); HBITMAP hbitmap = CreateDIBSection(screen_dc, reinterpret_cast<BITMAPINFO*>(&hdr), 0, &data, shared_section, 0); if (!hbitmap) { + CrashForBitmapAllocationFailure(width, height); return NULL; } diff --git a/skia/ext/canvas_paint_win.h b/skia/ext/canvas_paint_win.h index 9610025..f03ef55 100644 --- a/skia/ext/canvas_paint_win.h +++ b/skia/ext/canvas_paint_win.h @@ -109,10 +109,7 @@ class CanvasPaintT : public T { // inset pixels to the screen. const int width = ps_.rcPaint.right - ps_.rcPaint.left; const int height = ps_.rcPaint.bottom - ps_.rcPaint.top; - if (!canvas->initialize(width, height, opaque, NULL)) { - // Cause a deliberate crash; - *(char*) 0 = 0; - } + CHECK(canvas->initialize(width, height, opaque, NULL)); // This will bring the canvas into the screen coordinate system for the // dirty rect |