diff options
author | awr1 <41453959+awr1@users.noreply.github.com> | 2020-04-16 13:23:54 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-16 20:23:54 +0200 |
commit | b6f99409a967baebfda056a46f236643837e483b (patch) | |
tree | b7f13efa7b576bdfcbaaaeb43263477e35fdb2c3 | |
parent | 06e0c75ba9cd46cbbb09deb91db6f746fb62a820 (diff) | |
download | Nim-b6f99409a967baebfda056a46f236643837e483b.tar.gz |
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
-rw-r--r-- | lib/system/dyncalls.nim | 36 | ||||
-rw-r--r-- | lib/system/excpt.nim | 6 |
2 files changed, 30 insertions, 12 deletions
diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim index d16dbdf92..fe4797c5f 100644 --- a/lib/system/dyncalls.nim +++ b/lib/system/dyncalls.nim @@ -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.} = diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index 76d188ea6..aa3667226 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -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) |