Automattic / node-canvas

Node canvas is a Cairo backed Canvas implementation for NodeJS.
9.98k stars 1.15k forks source link

Error: The specified procedure could not be found. With sharp js. #930

Open SeanSobey opened 7 years ago

SeanSobey commented 7 years ago

Issue or Feature

When using this with sharp js canvas fails to load.

Error: The specified procedure could not be found. *\node_modules\canvas\build\Release\canvas.node

Steps to Reproduce

// Both work fine
require('canvas');
require("sharp");

// Throws error
require("sharp");
require('canvas');

Environment

zbjornson commented 7 years ago

I can reproduce this. Actual loader output:

3cf0:0e20 @ 45833265 - LdrLoadDll - ENTER: DLL name: \\?\D:\git\temp\node_modules\canvas\build\Release\canvas.node
3cf0:0e20 @ 45833265 - LdrpLoadDllInternal - ENTER: DLL name: \\?\D:\git\temp\node_modules\canvas\build\Release\canvas.node
3cf0:0e20 @ 45833265 - LdrpResolveDllName - ENTER: DLL name: \\?\D:\git\temp\node_modules\canvas\build\Release\canvas.node
3cf0:0e20 @ 45833265 - LdrpResolveDllName - RETURN: Status: 0x00000000
3cf0:0e20 @ 45833265 - LdrpMinimalMapModule - ENTER: DLL name: \\?\D:\git\temp\node_modules\canvas\build\Release\canvas.node
'node.exe' (Win32): Loaded 'D:\git\temp\node_modules\canvas\build\Release\canvas.node'. Symbols loaded.
3cf0:0e20 @ 45833265 - LdrpMinimalMapModule - RETURN: Status: 0x00000000
3cf0:0e20 @ 45833265 - LdrpFindKnownDll - ENTER: DLL name: libpng14-14.dll
3cf0:0e20 @ 45833265 - LdrpFindKnownDll - RETURN: Status: 0xc0000135
3cf0:1118 @ 45833265 - LdrpSearchPath - ENTER: DLL name: libpng14-14.dll
3cf0:1118 @ 45833265 - LdrpComputeLazyDllPath - INFO: DLL search path computed: \\?\D:\git\temp\node_modules\canvas\build\Release;C:\WINDOWS\SYSTEM32;C:\WINDOWS\system;C:\WINDOWS;.;D:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow;C:\Program Files (x86)\Microsoft SDKs\F#\4.0\Framework\v4.0\;C:\Program Files (x86)\MSBuild\14.0\bin;D:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\;D:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN;D:
3cf0:1118 @ 45833265 - LdrpResolveDllName - ENTER: DLL name: \\?\D:\git\temp\node_modules\canvas\build\Release\libpng14-14.dll
3cf0:1118 @ 45833265 - LdrpResolveDllName - RETURN: Status: 0x00000000
3cf0:1118 @ 45833265 - LdrpSearchPath - RETURN: Status: 0x00000000
3cf0:1118 @ 45833265 - LdrpMinimalMapModule - ENTER: DLL name: \\?\D:\git\temp\node_modules\canvas\build\Release\libpng14-14.dll
'node.exe' (Win32): Loaded 'D:\git\temp\node_modules\canvas\build\Release\libpng14-14.dll'. Module was built without symbols.
3cf0:1118 @ 45833281 - LdrpMinimalMapModule - RETURN: Status: 0x00000000
3cf0:1118 @ 45833281 - LdrpFindDllActivationContext - INFO: Probing for the manifest of DLL "\\?\D:\git\temp\node_modules\canvas\build\Release\libpng14-14.dll" failed with status 0xc0000089
3cf0:2030 @ 45833281 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlSizeHeap" by name
3cf0:2030 @ 45833281 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlReAllocateHeap" by name
3cf0:2030 @ 45833281 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlAllocateHeap" by name
3cf0:166c @ 45833281 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlDeleteCriticalSection" by name
3cf0:166c @ 45833281 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlEnterCriticalSection" by name
3cf0:2030 @ 45833281 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlDeleteCriticalSection" by name
3cf0:2030 @ 45833281 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlLeaveCriticalSection" by name
3cf0:2030 @ 45833281 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlEnterCriticalSection" by name
3cf0:2030 @ 45833281 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlInterlockedFlushSList" by name
3cf0:166c @ 45833281 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlInitializeCriticalSection" by name
3cf0:166c @ 45833281 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlLeaveCriticalSection" by name
3cf0:2030 @ 45833281 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlEncodePointer" by name
3cf0:2030 @ 45833281 - LdrpGetProcedureAddress - INFO: Locating procedure "RtlInitializeSListHead" by name
3cf0:2030 @ 45833281 - LdrpNameToOrdinal - WARNING: Procedure "cairo_svg_surface_create_for_stream" could not be located in DLL at base 0x0000000068DC0000.
3cf0:2030 @ 45833281 - LdrpReportError - ERROR: Locating export "cairo_svg_surface_create_for_stream" for DLL "\\?\D:\git\temp\node_modules\canvas\build\Release\canvas.node" failed with status: 0xc0000139.
Exception thrown at 0x00007FFE9A3F4B90 (ntdll.dll) in node.exe: 0xC0000139: Entry Point Not Found.

Version of libcairo-2.dll provided by sharp indeed is missing that function: image

Versus the version of libcairo-2.dll provided by canvas: image

I don't know why it's missing from the sharp version. They package a newer version (1.14) than canvas uses on Windows with the normal install instructions (1.10), but in any case that method has been around since Cairo 1.2.

Anyway, as far as I know, this is because when Windows searches for a DLL, if a DLL with the same module name is already loaded, that one will be used (see docs).

Is it viable to require canvas before sharp at least for now? A quick attempt to use DLL redirection with a canvas.node.local file didn't work, and libcairo-2.dll doesn't appear to contain a manifest to point to. Out of time right now to keep looking.

SeanSobey commented 7 years ago

Thanks for the further investigation, the error makes sense now that the function is missing on the other lib.

I have found an additional compilation however, the above workaround causes issues on Linux:

Segmentation fault

npm ERR! Linux 3.13.0-112-generic
node v7.10.0
npm  v4.2.0
code ELIFECYCLE
errno 139
Exit status 139

The SegFault appears to be caused by loading canvas before sharp.

So my ammended workaround is the glorious:

if (process.platform === 'win32') {
    require('canvas');
    require('sharp');
} else {
    require('sharp');
    require('canvas');
}

(The OP issue does not present on Linux it appears).

lovell commented 7 years ago

Hello, thanks to your investigation we discovered this was a problem with libvips' Windows build. https://github.com/jcupitt/build-win64/pull/13 will fix this for the next release, which will be available in a future sharp v0.19.x.

SeanSobey commented 7 years ago

Great! Thanks for the feedback.

zbjornson commented 7 years ago

Thanks @lovell !

It would still be nice to figure out how to get redirection working sometime so this can't happen in the first place.

SeanSobey commented 6 years ago

As of sharp 0.20.01 and canvas 2.0.0-alpha.11 this is still an issue.

BE-CH commented 3 years ago

For anyone wondering. Running sharp 0.28.1 and canvas 2.7.0 still has this issue.

cloewen8 commented 2 years ago

Has anyone found a configuration of versions for node-canvas and sharp that does work? Oddly only started experiencing this issue recently, was it reintroduced?

I have a dependency that relies on the latest versions of these. Thinking of using npm shrinkwrap to downgrade these sub-dependencies in the meantime.

lovell commented 2 years ago

@cloewen8 I believe this problem only affects Windows users that still rely upon GTK2 (2011) for canvas but very happy to be updated/corrected if things have improved - see https://sharp.pixelplumbing.com/install#canvas-and-windows

mctrafik commented 1 year ago

Still an issue in 2022. sharp@0.31.1 and canvas@2.10.1

m-s-morgan commented 1 year ago

Is there any workaround for this? Still an issue with:

Node: 18.13.0 Sharp: 0.31.3 Canvas: 2.11.0

lovell commented 1 year ago

https://sharp.pixelplumbing.com/install#canvas-and-windows

https://github.com/Automattic/node-canvas/issues/2155

ztomm commented 1 year ago

My workaround for now is to import node-canvas at the very beginning of the project and send a blank canvas to nirvana. This lets node-canvas and sharp work as usual.

// my-startfile.js

const { createCanvas } = require('canvas')
createCanvas(0, 0)

// ...

// somewhere else ...

const sharp = require('sharp');

When the fix comes sometime, this can simply be deleted again.

woxman commented 1 year ago

Is there any workaround for this? Still an issue with:

Node: 18.13.0 Sharp: 0.31.3 Canvas: 2.11.0

you can fix this problem??

woxman commented 1 year ago

Were you able to solve this problem?? please help me....

![Uploading pp.png…]()

Shubhamrawat5 commented 1 year ago

Error: The specified procedure could not be found. \?\C:\Users\shubh\OneDrive\Desktop\Github\whatsapp-bot-md\node_modules\canvas\build\Release\canvas.node

alecmev commented 10 months ago

Appears to play well with Sharp 0.32.5, no workarounds.