Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0004034OCamlotherlibspublic2006-05-29 17:002018-09-03 11:43
ReporterChristoph Bauer 
Assigned To 
PlatformOSWindowsOS Version
Product Version3.09.2 
Target VersionFixed in Version 
Summary0004034: Unix.getpid returns wrong result
DescriptionUnix.getpid returns a wrong (non-existing) processid.
To reproduce:

ocaml unix.cma
# Unix.getpid ();;

A working implementation of getpid.c could be

#include <mlvalues.h>
#include "unixsupport.h"

CAMLprim value unix_getpid(value unit)
  return Val_int( getpid() );
Attached Filespatch file icon ocaml-3.09.2-getpid.patch [^] (5,342 bytes) 2006-08-03 12:32 [Show Content]
diff file icon getpid-patch2.diff [^] (9,615 bytes) 2007-02-01 18:29 [Show Content]
diff file icon getpid-patch2b.diff [^] (9,595 bytes) 2007-02-02 11:06 [Show Content]
diff file icon getpid-patch2c.diff [^] (12,069 bytes) 2007-03-16 13:45 [Show Content]
diff file icon getpid-patch2d.diff [^] (12,137 bytes) 2007-03-16 16:56 [Show Content]
diff file icon getpid-patch2e.diff [^] (12,166 bytes) 2007-04-24 11:29 [Show Content]
diff file icon getpid-patch2f.diff [^] (13,034 bytes) 2008-01-22 17:33 [Show Content]
patch file icon getpid-3.11.0+beta1.patch [^] (20,574 bytes) 2008-11-12 10:33 [Show Content]
patch file icon ocaml-getpid-3.12.1.patch [^] (14,867 bytes) 2011-12-16 11:54 [Show Content]
patch file icon ocaml-getpid-4.01.0.patch [^] (16,054 bytes) 2014-05-20 10:14 [Show Content]
patch file icon ocaml-getpid-4.01.0a.patch [^] (14,966 bytes) 2014-05-20 11:51 [Show Content]

- Relationships

-  Notes
Christoph Bauer (reporter)
2006-05-29 17:01

Important note: the platform is windows (mingw-version in my case).
xleroy (administrator)
2006-06-08 17:10

There are no strict equivalent to Unix's process IDs in the Win32 API,
so in what sense is the returned PID "wrong"??

Caml uses process handles as closest equivalents of process IDs for the
Unix.create_process* and Unix.waitpid and Unix.getpid functions. Returning
anything else from Unix.getpid or Unix.create_process* would break Unix.waitpid.
Christoph Bauer (reporter)
2006-06-09 13:59

There is a function GetCurrentProcessID. The task manager
shows a column with a pid. This pid could be used by an external
program to kill a process or even to run cygwins gdb with the option

winwait.c could make use of OpenProcess, which takes the
pid and returns the handle.
xleroy (administrator)
2006-06-10 11:11

I keep that as a feature wish.
Christoph Bauer (reporter)
2006-08-03 12:39

I attached an patch that seems to work:

  o Unix.getpid() returns a pid like the taskmanager
  o create_process + winwait works correct (at least in my test)
  o there is no open process handle.

My tests are done with the mingw version. I found the API
description on MSDN.

In the original implementation closes never the hProcess-Handle
from the PROCESS_INFORMATION struct pi. MSDN states this should
be done. My patch closes this handle directly after create_process,
so this problems is solved, too.
Christoph Bauer (reporter)
2006-08-03 12:42

Please apply the patch in the directory `ocaml-3.09.2/otherlibs/win32unix'.
Christoph Bauer (reporter)
2007-01-22 10:24

I tested the patch now a long time and had never a problem with it.

This entry could be counted as bug because of the process handle leak under windows...
xleroy (administrator)
2007-01-30 14:19

I tried the patch but runs into errors returned by OpenProcess.
I believe the problem is this: if Unix.waitpid is called for a process that has already terminated, its processID is invalid (Windows doesn't keep the process around if its handles are closed) and there is no way to recover its handle and therefore its exit code. Try for instance the following example:

  let ic = Unix.open_process_in "dir c:\\" in
  begin try
    while true do
      print_string (input_line ic); print_newline()
  with End_of_file -> ()
  ignore (Unix.close_process_in ic)

Don't you get an error on close_process_in?
Christoph Bauer (reporter)
2007-02-01 12:21

I guess you are right. With your example I get the error sometimes. So a Unix.sleep and now I get the error more reliably:

let ic = Unix.open_process_in "dir c:\\" in
  begin try
    while true do
      print_string (input_line ic); print_newline()
  with End_of_file -> ()
  Unix.sleep 1;
  ignore (Unix.close_process_in ic);;

There are two possible solutions. The simple one:
GetLastError() returns ERROR_INVALID_PARAMETER. This could be catched
and a zero exit code could be returned. The main drawback is that the return
code nonsense. (Another drawback for my approach is
that windows theoretical could reuse the given pid.)

The second solution could be a internal table that stores for each pid the process information. Then the job of waitpid would be to free the internal handle. The table could be realized as a simple list or a simple hash table.

I try to implement the second approach.
Christoph Bauer (reporter)
2007-02-01 18:31

The new patch implements a pid table of PROCESS_INFORMATION. (binary search,
dynamic storage allocation). The code for table management is in two new files pidtable.h and pidtable.c.
Christoph Bauer (reporter)
2007-03-16 12:48

There's a stupid bug in patch 2b. I'll prepare a new one.
Christoph Bauer (reporter)
2008-01-22 17:34

The patch 2e was quite good. 2f is a patch against 3.10.1.
Christoph Bauer (reporter)
2011-12-16 11:56

patch against 3.12.1. compiles with msvc.
Christoph Bauer (reporter)
2014-05-20 10:25
edited on: 2014-05-20 11:52

patch against 4.01.0 uploaded: ocaml-getpid-4.01.0a.patch

gabelevi (reporter)
2016-07-25 21:45

(It's very possible that I'm missing some historical information about Windows. I did notice that some functions, like GetCurrentProcessID, were introduced with Windows XP, so maybe Windows didn't used to have a notion of Process IDs).

It does appear that Windows has the concept of Process IDs, in addition to Process Handles. I think it would be better if the various functions that return references to a process (like Unix.getpid and Unix.create_process) and the various functions that take a reference to a process (like Unix.waitpid and Unix.kill) used Process IDs instead of Process Handles.

I have code that I am porting to Windows. While the create_process/waitpid pattern still works, there are other patterns that break. I need to manually translate Process Handles to Process IDs when I want to output the "pid" to stdout, a log file, etc. Also, I need to manually translate Process IDs to Process Handles when I read the "pid" from stdin, a file, etc.

Process IDs are portable across processes in a way that Process Handles are not. So while Process Handles work well enough as an opaque pseudo-pid, I think Process IDs would work just as well and would prevent unnecessary translation when outputting and inputting pids.

(For reference, here is the change I had to make to get some code working on Windows. Some of the code is responsible for logging pids to a file in case they need to be manually terminated later, and has to translate Process Handles to Process IDs. The code that reads these Process IDs needs to translate them back into Process Handles to terminate those processes. The third affected piece of code just reports to stdout the pid of a created process. [^])

- Issue History
Date Modified Username Field Change
2006-05-29 17:00 Christoph Bauer New Issue
2006-05-29 17:01 Christoph Bauer Note Added: 0003649
2006-06-08 17:10 xleroy Note Added: 0003660
2006-06-09 13:59 Christoph Bauer Note Added: 0003663
2006-06-10 11:11 xleroy Note Added: 0003666
2006-06-10 11:11 xleroy Severity minor => feature
2006-06-10 11:11 xleroy Status new => acknowledged
2006-08-03 12:32 Christoph Bauer File Added: ocaml-3.09.2-getpid.patch
2006-08-03 12:39 Christoph Bauer Note Added: 0003725
2006-08-03 12:42 Christoph Bauer Note Added: 0003726
2007-01-22 10:24 Christoph Bauer Note Added: 0003895
2007-01-30 14:19 xleroy Note Added: 0003909
2007-02-01 12:21 Christoph Bauer Note Added: 0003910
2007-02-01 18:29 Christoph Bauer File Added: getpid-patch2.diff
2007-02-01 18:31 Christoph Bauer Note Added: 0003912
2007-02-02 11:06 Christoph Bauer File Added: getpid-patch2b.diff
2007-03-16 12:48 Christoph Bauer Note Added: 0003978
2007-03-16 13:45 Christoph Bauer File Added: getpid-patch2c.diff
2007-03-16 16:56 Christoph Bauer File Added: getpid-patch2d.diff
2007-04-24 11:29 Christoph Bauer File Added: getpid-patch2e.diff
2008-01-22 17:33 Christoph Bauer File Added: getpid-patch2f.diff
2008-01-22 17:34 Christoph Bauer Note Added: 0004435
2008-11-12 10:33 Christoph Bauer File Added: getpid-3.11.0+beta1.patch
2011-12-16 11:54 Christoph Bauer File Added: ocaml-getpid-3.12.1.patch
2011-12-16 11:56 Christoph Bauer Note Added: 0006322
2013-09-03 17:11 doligez Tag Attached: patch
2013-09-03 17:11 doligez OS => Windows
2014-05-20 10:14 Christoph Bauer File Added: ocaml-getpid-4.01.0.patch
2014-05-20 10:25 Christoph Bauer Note Added: 0011524
2014-05-20 11:51 Christoph Bauer File Added: ocaml-getpid-4.01.0a.patch
2014-05-20 11:52 Christoph Bauer Note Edited: 0011524 View Revisions
2016-07-25 21:45 gabelevi Note Added: 0016133
2016-12-07 18:45 shinwell Category OCaml general => OCaml otherlibs
2017-02-23 16:42 doligez Category OCaml otherlibs => otherlibs

Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker