Skip to content

Commit

Permalink
win32: provide error messages when loading foreign libraries.
Browse files Browse the repository at this point in the history
Decode the error codes into messages.
  • Loading branch information
stassats committed Nov 11, 2013
1 parent 1975bd0 commit a4c87f2
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 31 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ changes relative to sbcl-1.1.13:
Thanks to Jan Moringen. (lp#1249055)
* enhancement: Top-level defmethod without defgeneric no longer causes
undefined-function warnings in subsequent forms. (lp#503095)
* enhancement: Errors during loading foreign libraries on Windows now
include error messages instead of error codes.
* bug fix: EQUALP now compares correctly structures with raw slots larger
than a single word.
* bug fix: contribs couldn't be built on Windows with MinGW.
Expand Down
2 changes: 1 addition & 1 deletion contrib/sb-bsd-sockets/sockets.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ request an input stream and get an output stream in response\)."
(or (socket-error-symbol c) (socket-error-errno c))
#+cmu (sb-unix:get-unix-error-msg num)
#+sbcl
#+win32 (sb-win32::get-last-error-message num)
#+win32 (sb-win32:format-system-message num)
#-win32 (sb-int:strerror num)))))
(:documentation "Common base class of socket related conditions."))

Expand Down
2 changes: 1 addition & 1 deletion package-data-list.lisp-expr
Original file line number Diff line number Diff line change
Expand Up @@ -2925,7 +2925,7 @@ SBCL itself"
"FILE-TRUNCATE-EXISTING"
"FLUSH-CONSOLE-INPUT-BUFFER"
"FLUSH-VIEW-OF-FILE"
"FORMAT-MESSAGE"
"FORMAT-SYSTEM-MESSAGE"
"GET-FILE-ATTRIBUTES"
"GET-FILE-SIZE-EX"
"GET-FILE-TYPE"
Expand Down
10 changes: 4 additions & 6 deletions src/code/win32-foreign-load.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
(handle hinstance)
(symbol c-string))

(define-alien-routine ("GetLastError" getlasterror) unsigned-int)

(define-alien-routine ("SetStdHandle" set-std-handle)
void
(id int)
Expand Down Expand Up @@ -61,8 +59,8 @@
(aver namestring)
(when (zerop handle)
(setf (shared-object-handle obj) nil)
(error "Error opening shared object ~S:~% ~A."
namestring (getlasterror)))
(error "Error opening shared object ~S:~% ~A"
namestring (sb!win32:format-system-message (sb!win32:get-last-error))))
(setf (shared-object-handle obj) handle)
handle)
(extern-alien "runtime_module_handle" hinstance)))
Expand All @@ -72,9 +70,9 @@
(unless (freelibrary (shared-object-handle obj))
(cerror "Ignore the error and continue as if closing succeeded."
"FreeLibrary() caused an error while trying to close ~
shared object ~S: ~S"
shared object ~S:~% ~A"
(shared-object-namestring obj)
(getlasterror)))
(sb!win32:format-system-message (sb!win32:get-last-error))))
(setf (shared-object-handle obj) nil)))

(defun find-dynamic-foreign-symbol-address (symbol)
Expand Down
26 changes: 6 additions & 20 deletions src/code/win32.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -74,21 +74,6 @@
;;; last-error code is maintained on a per-thread basis.
(define-alien-routine ("GetLastError" get-last-error) dword)

;;; Flag constants for FORMAT-MESSAGE.
(defconstant format-message-from-system #x1000)

;;; Format an error message based on a lookup table. See MSDN for the
;;; full meaning of the all options---most are not used when getting
;;; system error codes.
(define-alien-routine ("FormatMessageA" format-message) dword
(flags dword)
(source (* t))
(message-id dword)
(language-id dword)
(buffer c-string)
(size dword)
(arguments (* t)))

;;;; File Handles

;;; Historically, SBCL on Windows used CRT (lowio) file descriptors,
Expand Down Expand Up @@ -521,16 +506,17 @@
(defmacro void-syscall* ((name &rest arg-types) &rest args)
`(syscall* (,name ,@arg-types) (values t 0) ,@args))

(defun get-last-error-message (err)
(defun format-system-message (err)
"http:https://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/retrieving_the_last_error_code.asp"
(let ((message
(with-alien ((amsg (* char)))
(syscall (("FormatMessage" t)
dword dword dword dword dword (* (* char)) dword dword)
(cast-and-free amsg :free-function local-free)
(logior FORMAT_MESSAGE_ALLOCATE_BUFFER
FORMAT_MESSAGE_FROM_SYSTEM
FORMAT_MESSAGE_MAX_WIDTH_MASK)
(logior format-message-allocate-buffer
format-message-from-system
format-message-max-width-mask
format-message-ignore-inserts)
0 err 0 (addr amsg) 0 0))))
(and message (string-right-trim '(#\Space) message))))

Expand All @@ -540,7 +526,7 @@
(error "~%Win32 Error [~A] - ~A~%~A"
,func-name
err-code
(get-last-error-message err-code))))
(format-system-message err-code))))

(defun get-folder-namestring (csidl)
"http:https://msdn.microsoft.com/library/en-us/shellcc/platform/shell/reference/functions/shgetfolderpath.asp"
Expand Down
7 changes: 4 additions & 3 deletions tools-for-build/grovel-headers.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,10 @@ main(int argc, char *argv[])

printf(";;; FormatMessage\n");

defconstant("FORMAT_MESSAGE_ALLOCATE_BUFFER", FORMAT_MESSAGE_ALLOCATE_BUFFER);
defconstant("FORMAT_MESSAGE_FROM_SYSTEM", FORMAT_MESSAGE_FROM_SYSTEM);
defconstant("FORMAT_MESSAGE_MAX_WIDTH_MASK", FORMAT_MESSAGE_MAX_WIDTH_MASK);
defconstant("format-message-allocate-buffer", FORMAT_MESSAGE_ALLOCATE_BUFFER);
defconstant("format-message-from-system", FORMAT_MESSAGE_FROM_SYSTEM);
defconstant("format-message-max-width-mask", FORMAT_MESSAGE_MAX_WIDTH_MASK);
defconstant("format-message-ignore-inserts", FORMAT_MESSAGE_IGNORE_INSERTS);

printf(";;; Errors\n");

Expand Down

0 comments on commit a4c87f2

Please sign in to comment.