summaryrefslogtreecommitdiffstats
path: root/skia
diff options
context:
space:
mode:
authortwiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-10 18:31:20 +0000
committertwiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-10 18:31:20 +0000
commitd9f90a8f48b135757bd5154ba568ab68039ca8f0 (patch)
tree6c5dad636b244b0b5e50b7b0e828fccff850744f /skia
parent1a4d71e7c54f810961d2e7463e928f28bc5e4c27 (diff)
downloadchromium_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.cc57
-rw-r--r--skia/ext/canvas_paint_win.h5
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