Skip to content

Commit

Permalink
Revert 109461 -
Browse files Browse the repository at this point in the history
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, 104063
TEST=NONE

Review URL: http://codereview.chromium.org/8509030

TBR=twiz@chromium.org

Review URL: http://codereview.chromium.org/8565027

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@109978 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
twiz@chromium.org committed Nov 14, 2011
1 parent dc8347f commit cb36dc7
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 58 deletions.
57 changes: 0 additions & 57 deletions skia/ext/bitmap_platform_device_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,64 +7,12 @@

#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(
Expand Down Expand Up @@ -169,16 +117,11 @@ 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;
}

Expand Down
5 changes: 4 additions & 1 deletion skia/ext/canvas_paint_win.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ 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;
CHECK(canvas->initialize(width, height, opaque, NULL));
if (!canvas->initialize(width, height, opaque, NULL)) {
// Cause a deliberate crash;
*(char*) 0 = 0;
}

// This will bring the canvas into the screen coordinate system for the
// dirty rect
Expand Down

0 comments on commit cb36dc7

Please sign in to comment.