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:
parent
06e0c75ba9
commit
b6f99409a9
2 changed files with 30 additions and 12 deletions
|
|
@ -19,18 +19,34 @@ const
|
||||||
|
|
||||||
proc nimLoadLibraryError(path: string) =
|
proc nimLoadLibraryError(path: string) =
|
||||||
# carefully written to avoid memory allocation:
|
# carefully written to avoid memory allocation:
|
||||||
cstderr.rawWrite("could not load: ")
|
|
||||||
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: "
|
const prefix = "could not load: "
|
||||||
var msg: array[1000, char]
|
cstderr.rawWrite(prefix)
|
||||||
copyMem(msg[0].addr, prefix.cstring, prefix.len)
|
cstderr.rawWrite(path)
|
||||||
copyMem(msg[prefix.len].addr, path.cstring, min(path.len + 1, 1000 - prefix.len))
|
when not defined(nimDebugDlOpen) and not defined(windows):
|
||||||
|
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)
|
discard MessageBoxA(nil, msg[0].addr, nil, 0)
|
||||||
|
cstderr.rawWrite("\n")
|
||||||
quit(1)
|
quit(1)
|
||||||
|
|
||||||
proc procAddrError(name: cstring) {.compilerproc, nonReloadable, hcrInline.} =
|
proc procAddrError(name: cstring) {.compilerproc, nonReloadable, hcrInline.} =
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,15 @@ var
|
||||||
## instead of `stdmsg.write` when printing stacktrace.
|
## instead of `stdmsg.write` when printing stacktrace.
|
||||||
## Unstable API.
|
## 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):
|
when not defined(windows) or not defined(guiapp):
|
||||||
proc writeToStdErr(msg: cstring) = rawWrite(cstderr, msg)
|
proc writeToStdErr(msg: cstring) = rawWrite(cstderr, msg)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
proc MessageBoxA(hWnd: pointer, lpText, lpCaption: cstring, uType: int): int32 {.
|
proc MessageBoxA(hWnd: pointer, lpText, lpCaption: cstring, uType: int): int32 {.
|
||||||
header: "<windows.h>", nodecl.}
|
header: "<windows.h>", nodecl.}
|
||||||
|
|
||||||
proc writeToStdErr(msg: cstring) =
|
proc writeToStdErr(msg: cstring) =
|
||||||
discard MessageBoxA(nil, msg, nil, 0)
|
discard MessageBoxA(nil, msg, nil, 0)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue