Skia Crashing on Windows

428 views
Skip to first unread message

Tyler Genter

unread,
Jan 10, 2023, 12:06:59 PM1/10/23
to skia-discuss
Skia is crashing on Windows x64, with the following example:

SkColor colors2[] = { SK_ColorBLUE, SK_ColorRED };
SkPoint pts[] = { {0.0f, 0.0f}, {100.0f, 100.0f} };

int main()
{
    auto rasterSurface =    SkSurface::MakeRasterN32Premul(100, 100);
    SkCanvas* canvas = rasterSurface->getCanvas();

    auto paint = new SkPaint();
    auto gradient = SkGradientShader::MakeLinear(
        pts,
        colors2,
        NULL,
        2,
        SkTileMode::kClamp,
        0,
        NULL);
    //_paint->setColor(0xff00ff00);
    paint->setShader(gradient);
    canvas->drawPaint(*paint);
    canvas->flush();
}

The drawPaint is crashing, but only with a linear shader. If I create a paint with a solid color, it works.

The following is the stack trace:
     0000000000000000()    Unknown
>    skia.dll!SkShaderBase::makeContext(const SkShaderBase::ContextRec & rec, SkArenaAlloc * alloc) Line 65    C++
     skia.dll!SkBlitter::Choose(const SkPixmap & device, const SkMatrixProvider & matrixProvider, const SkPaint & origPaint, SkArenaAlloc * alloc, bool drawCoverage, sk_sp<SkShader> clipShader, const SkSurfaceProps & props) Line 796    C++
     [Inline Frame] skia.dll!SkAutoBlitterChoose::choose(const SkDraw & draw, const SkMatrixProvider * matrixProvider, const SkPaint & paint, bool drawCoverage) Line 39    C++
     [Inline Frame] skia.dll!SkAutoBlitterChoose::SkAutoBlitterChoose(const SkDraw & draw, const SkMatrixProvider * matrixProvider, const SkPaint & paint, bool drawCoverage) Line 27    C++
     skia.dll!SkDraw::drawPaint(const SkPaint & paint) Line 89    C++
     skia.dll!SkBitmapDevice::drawPaint(const SkPaint & paint) Line 336    C++
     skia.dll!SkCanvas::internalDrawPaint(const SkPaint & paint) Line 2056    C++
     skia.dll!SkCanvas::drawPaint(const SkPaint & paint) Line 1836    C++
     ConsoleApplication2.exe!main() Line 34    C++
     [External Code]    

So what I think is happening, is SkShaderBase::onMakeContext is a virtual method, and somehow the vtable is getting corrupt and onMakeContext is a null pointer.

John Stiles

unread,
Jan 10, 2023, 1:58:12 PM1/10/23
to skia-d...@googlegroups.com
Are you able to reproduce the issue in a Fiddle?

I experimented with it and wasn't able to reproduce any problem:

I did think of two minor issues, but I don't think either is the root cause:
- You might want to call SkGraphics::Init, but I don't think that is the problem.
- Your code leaks the paint variable (you don't need to use new here at all).


--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/skia-discuss/406ffb5d-f02f-4862-b0cb-5f6a42343326n%40googlegroups.com.

Tyler Genter

unread,
Jan 10, 2023, 2:09:26 PM1/10/23
to skia-discuss
Not able to reproduce in a Fiddle.

Calling SkGraphics::Init() does not fix it.

I'm aware I'm leaking paint, this is a simplification of a more complicated library.

John Stiles

unread,
Jan 10, 2023, 2:36:58 PM1/10/23
to skia-d...@googlegroups.com
Thanks for the quick response.

I notice that you're using Skia in a DLL—is there any chance that the DLL you're using doesn't match the Skia code/headers that you are compiling with? It would make sense for Skia to crash in inexplicable ways if the DLL were from a different build of Skia, or even if there was a configuration difference between the app and the DLL. Skia doesn't try to detect these mismatches or guard against them; it will just lead to a crash.

Tyler Genter

unread,
Jan 10, 2023, 5:00:19 PM1/10/23
to skia-discuss
I'm using the correct DLL. If I delete it, I get an error telling me skia.dll can't be found, so I know it isn't including a random one from someplace else.

John Stiles

unread,
Jan 10, 2023, 5:02:57 PM1/10/23
to skia-d...@googlegroups.com
Can you try static-linking Skia instead of using a DLL? That would give a stronger guarantee that everything is in sync. "It's using the DLL from the folder I expected it to" is a great baseline check, but it's not necessarily proof that the DLL was built with the same code and build configuration as the EXE.


Brian Osman

unread,
Jan 10, 2023, 7:21:19 PM1/10/23
to skia-d...@googlegroups.com
Yes, just to clarify one of the risks that John is alluding to: If you're building Skia and your client application with different flags (eg, SK_DEBUG is set inconsistently), you run the risk of some classes having different memory layout for code that's in the DLL, vs. code that's in your application. (That application code can still depend on the class layout, when there are inline methods in the Skia headers).

Tyler Genter

unread,
Jan 11, 2023, 1:59:41 PM1/11/23
to skia-discuss
I can't statically link it. Linker gives an internal error:

1>skia.lib(skia.SkColorFilter_Matrix.obj) : fatal error LNK1000: Internal error during IMAGE::Pass2

LNK1000 is an internal error in the linker, the recommended solution is to reboot your computer and update Visual Studio (I did both).

Tyler Genter

unread,
Jan 12, 2023, 12:31:48 AM1/12/23
to skia-discuss
Ok, having stared at too much assembly, I found the problem.

The struct sk_sp<T> is basically just a thin wrapper around a single pointer. SkPaint.SetShader (as compiled by clang) is expecting that struct to be passed by value (since it's basically just a pointer). I'm compiling my test program with CL. CL passes it by reference. Setting my compiler to clang fixed it. I assume it has something to do with:
#define SK_SP_TRIVIAL_ABI [[clang::trivial_abi]]
but I dunno what the correct statement would be for CL.

Theoretically, C++ abi is stable across compilers (https://learn.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017?view=msvc-170), but I guess this is the difference between theory and actual.

bungeman

unread,
Jan 12, 2023, 10:58:03 AM1/12/23
to skia-discuss
Interesting. Probably the clang::trivial_abi use should be opt-in instead of opt-out. Skia does really want to be compiled with clang, which users are aware of and do, but then they may wish to build their own application with msvc's cl, and opaquely breaking the ABI this way without notice is probably a bit much. This was added in https://skia.googlesource.com/skia/+/2c8222767b806b0ee5b6141d6463f0eb5eb78886 . I'll take a look and see what we might want to do about it. At the very least it looks like this is a good reason to allow turning this off.

Ben Wagner

unread,
Jan 24, 2023, 3:38:35 PM1/24/23
to skia-discuss
I've landed a change [0] to make this optional and default to off in a
Skia GN build with `is_official_build`.

[0] https://skia.googlesource.com/skia.git/+show/3cd41698078075347badbeb64e546d8539c29ff8

Noel Grandin

unread,
Jan 27, 2023, 7:47:20 AM1/27/23
to skia-discuss
Hi

Just to confirm 

(*) we use Skia in LibreOffice.
(*) I tried to update Skia to m110
(*) We compile Skia with the clang included with Visual Studio (clang-15 in the case of Visual Studio 2022)
(*) But we compile other code (that calls into Skia) with Visual Studio
(*) This resulted in the SkPaint::setShader call setting garbage into SkPaint::fShader

Thanks, Noel Grandin
Reply all
Reply to author
Forward
0 new messages