added extended msg for failed library loads w/ incorrect DLL formats (#13950)

* added extended msg for failed library loads w/ incorrect DLL formats

* missing colon

* fix GetLastError()

* make GetLastError() available for windows console apps

* remove premature nullchar if outputting extra message

* if-protect nullchar detection

* better fix for message box code
This commit is contained in:
awr1
2020-04-16 13:23:54 -05:00
committed by GitHub
parent 06e0c75ba9
commit b6f99409a9
2 changed files with 30 additions and 12 deletions

View File

@@ -19,18 +19,34 @@ const
proc nimLoadLibraryError(path: string) =
# carefully written to avoid memory allocation:
cstderr.rawWrite("could not load: ")
const prefix = "could not load: "
cstderr.rawWrite(prefix)
cstderr.rawWrite(path)
cstderr.rawWrite("\n")
when not defined(nimDebugDlOpen) and not defined(windows):
cstderr.rawWrite("compile with -d:nimDebugDlOpen for more information\n")
when defined(windows) and defined(guiapp):
# Because console output is not shown in GUI apps, display error as message box:
const prefix = "could not load: "
var msg: array[1000, char]
copyMem(msg[0].addr, prefix.cstring, prefix.len)
copyMem(msg[prefix.len].addr, path.cstring, min(path.len + 1, 1000 - prefix.len))
discard MessageBoxA(nil, msg[0].addr, nil, 0)
cstderr.rawWrite("\n(compile with -d:nimDebugDlOpen for more information)")
when defined(windows):
const badExe = "\n(bad format; library may be wrong architecture)"
let loadError = GetLastError()
if loadError == ERROR_BAD_EXE_FORMAT:
cstderr.rawWrite(badExe)
when defined(guiapp):
# Because console output is not shown in GUI apps, display the error as a
# message box instead:
var
msg: array[1000, char]
msgLeft = msg.len - 1 # leave (at least) one for nullchar
msgIdx = 0
copyMem(msg[msgIdx].addr, prefix.cstring, prefix.len)
msgLeft -= prefix.len
msgIdx += prefix.len
let pathLen = min(path.len, msgLeft)
copyMem(msg[msgIdx].addr, path.cstring, pathLen)
msgLeft -= pathLen
msgIdx += pathLen
if loadError == ERROR_BAD_EXE_FORMAT and msgLeft >= badExe.len:
copyMem(msg[msgIdx].addr, badExe.cstring, badExe.len)
discard MessageBoxA(nil, msg[0].addr, nil, 0)
cstderr.rawWrite("\n")
quit(1)
proc procAddrError(name: cstring) {.compilerproc, nonReloadable, hcrInline.} =

View File

@@ -17,13 +17,15 @@ var
## instead of `stdmsg.write` when printing stacktrace.
## Unstable API.
when defined(windows):
proc GetLastError(): int32 {.header: "<windows.h>", nodecl.}
const ERROR_BAD_EXE_FORMAT = 193
when not defined(windows) or not defined(guiapp):
proc writeToStdErr(msg: cstring) = rawWrite(cstderr, msg)
else:
proc MessageBoxA(hWnd: pointer, lpText, lpCaption: cstring, uType: int): int32 {.
header: "<windows.h>", nodecl.}
proc writeToStdErr(msg: cstring) =
discard MessageBoxA(nil, msg, nil, 0)