Skip to content

Commit 2781979

Browse files
MisterDAdra27
andcommitted
Display Windows NTSTATUS exit codes in hex
On Windows, "negative" exit codes are probably NTSTATUS values. For example, if a program accesses an invalid memory location, Unix sends a SIGSEGV signal which, if unhandled, will terminate the process (setting some kind of non-zero exit code - for example, Linux sets the exit code to 128 + signal number to give a fairly memorable 139). In the equivalent scenario, Windows throws an EXCEPTION_ACCESS_VIOLATION which, if handled by the default exception handler, will terminate the process with exit code STATUS_ACCESS_VIOLATION. These codes are large negative numbers, which are not terribly memorable in decimal, so for negative exit codes we instead display them in hexadecimal as 0xc0000005 is slightly more memorable than -1073741819. Co-authored-by: David Allsopp <david.allsopp@metastack.com> Signed-off-by: Antonin Décimo <antonin@tarides.com>
1 parent b172bca commit 2781979

1 file changed

Lines changed: 9 additions & 3 deletions

File tree

lib/os.ml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ let pp_cmd f (cmd, argv) =
3434
let argv = if cmd = "" then argv else cmd :: argv in
3535
Fmt.hbox Fmt.(list ~sep:sp (quote string)) f argv
3636

37+
let pp_exit_status f n =
38+
if Sys.win32 && n < 0 then
39+
Fmt.pf f "0x%08lx" (Int32.of_int n)
40+
else
41+
Fmt.int f n
42+
3743
let redirection = function
3844
| `FD_move_safely x -> `FD_copy x.raw
3945
| `Dev_null -> `Dev_null
@@ -87,7 +93,7 @@ let process_result ~pp proc =
8793
| Unix.WSTOPPED x -> Fmt.error_msg "%t stopped with signal %a" pp Fmt.Dump.signal x)
8894
>>= function
8995
| Ok 0 -> Lwt_result.return ()
90-
| Ok n -> Lwt.return @@ Fmt.error_msg "%t failed with exit status %d" pp n
96+
| Ok n -> Lwt.return @@ Fmt.error_msg "%t failed with exit status %a" pp pp_exit_status n
9197
| Error e -> Lwt_result.fail (e : [`Msg of string] :> [> `Msg of string])
9298

9399
(* Overridden in unit-tests *)
@@ -97,15 +103,15 @@ let exec_result ?cwd ?stdin ?stdout ?stderr ~pp ?(is_success=((=) 0)) ?(cmd="")
97103
Logs.info (fun f -> f "Exec %a" pp_cmd (cmd, argv));
98104
!lwt_process_exec ?cwd ?stdin ?stdout ?stderr ~pp (cmd, Array.of_list argv) >>= function
99105
| Ok n when is_success n -> Lwt_result.ok Lwt.return_unit
100-
| Ok n -> Lwt.return @@ Fmt.error_msg "%t failed with exit status %d" pp n
106+
| Ok n -> Lwt.return @@ Fmt.error_msg "%t failed with exit status %a" pp pp_exit_status n
101107
| Error e -> Lwt_result.fail (e : [`Msg of string] :> [> `Msg of string])
102108

103109
let exec ?timeout ?cwd ?stdin ?stdout ?stderr ?(is_success=((=) 0)) ?(cmd="") argv =
104110
Logs.info (fun f -> f "Exec %a" pp_cmd (cmd, argv));
105111
let pp f = pp_cmd f (cmd, argv) in
106112
!lwt_process_exec ?timeout ?cwd ?stdin ?stdout ?stderr ~pp (cmd, Array.of_list argv) >>= function
107113
| Ok n when is_success n -> Lwt.return_unit
108-
| Ok n -> Fmt.failwith "%t failed with exit status %d" pp n
114+
| Ok n -> Fmt.failwith "%t failed with exit status %a" pp pp_exit_status n
109115
| Error (`Msg m) -> failwith m
110116

111117
let running_as_root = not (Sys.unix) || Unix.getuid () = 0

0 commit comments

Comments
 (0)