x64 hg.exe
Adrian Buehlmann
adrian at cadifra.com
Fri Jun 22 12:26:44 CDT 2012
On 2012-06-22 16:38, Adrian Buehlmann wrote:
> On 2012-06-22 13:07, Adrian Buehlmann wrote:
>> On 2012-06-22 03:42, Adrian Buehlmann wrote:
>>> I've built an exemaker exe
>>>
>>> hg-x64-385eaa517487.exe
>>
>> No luck. The serve tests fail with the exe when -d is specified:
>>
>> $ hg --traceback serve -n test -p 20059 -d --pid-file=hg.pid -E errors.log
>> Traceback (most recent call last):
>> File "C:\Users\adi\hgrepos\hg-main\mercurial\dispatch.py", line 88, in _runcatch
>> return _dispatch(req)
>> File "C:\Users\adi\hgrepos\hg-main\mercurial\dispatch.py", line 739, in _dispatch
>> cmdpats, cmdoptions)
>> File "C:\Users\adi\hgrepos\hg-main\mercurial\dispatch.py", line 513, in runcommand
>> ret = _runcommand(ui, options, cmd, d)
>> File "C:\Users\adi\hgrepos\hg-main\mercurial\dispatch.py", line 829, in _runcommand
>> return checkargs()
>> File "C:\Users\adi\hgrepos\hg-main\mercurial\dispatch.py", line 800, in checkargs
>> return cmdfunc()
>> File "C:\Users\adi\hgrepos\hg-main\mercurial\dispatch.py", line 736, in <lambda>
>> d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
>> File "C:\Users\adi\hgrepos\hg-main\mercurial\util.py", line 475, in check
>> return func(*args, **kwargs)
>> File "C:\Users\adi\hgrepos\hg-main\mercurial\extensions.py", line 139, in wrap
>> util.checksignature(origfn), *args, **kwargs)
>> File "C:\Users\adi\hgrepos\hg-main\mercurial\util.py", line 475, in check
>> return func(*args, **kwargs)
>> File "C:\Users\adi\hgrepos\hg-main\hgext\mq.py", line 3505, in mqcommand
>> return orig(ui, repo, *args, **kwargs)
>> File "C:\Users\adi\hgrepos\hg-main\mercurial\util.py", line 475, in check
>> return func(*args, **kwargs)
>> File "C:\Users\adi\hgrepos\hg-main\mercurial\commands.py", line 5120, in serve
>> cmdutil.service(opts, initfn=service.init, runfn=service.run)
>> File "C:\Users\adi\hgrepos\hg-main\mercurial\cmdutil.py", line 486, in service
>> raise util.Abort(_('child process failed to start'))
>> Abort: child process failed to start
>> abort: child process failed to start
>>
>> And it's not because of a problem with the port. An identical
>>
>> $ python hg.py --traceback serve -n test -p 20070 -d --pid-file=hg.pid -E errors.log
>>
>> adi at kork /hgrepos/hg-main
>>
>> works.
>>
>> Without -d, the exe works:
>>
>> $ hg --traceback serve -n test -p 20059
>>
>> So there's a problem with --daemon in combination with the exe.
>
> With
>
> diff --git a/mercurial/util.py b/mercurial/util.py
> --- a/mercurial/util.py
> +++ b/mercurial/util.py
> @@ -1395,6 +1395,7 @@
> if SIGCHLD is not None:
> prevhandler = signal.signal(SIGCHLD, handler)
> try:
> + print "calling spawndetached():", args
> pid = spawndetached(args)
> while not condfn():
> if ((pid in terminated or not testpid(pid))
>
> and hg.exe, I see (in sh of MSYS):
>
> $ hg --traceback serve -n test -p 20070 -d --pid-file=hg.pid -E errors.log
> calling spawndetached(): ['C:\\Users\\adi\\hgrepos\\hg-main\\hg.exe', 'C:\\Users\\adi\\hgrepos\\hg-main\\hg.py', '--traceback', 'serve', '-n', 'test', '-p', '20070', '-d', '--pid-file=hg.pid', '-E', 'errors.log', '--daemon-pipefds=c:\\tmp\\hg-service-za7au5']
>
> If I use the hg file (with Python in PATH), I see:
>
> $ hg --traceback serve -n test -p 20070 -d --pid-file=hg.pid -E errors.log
> calling spawndetached(): ['c:\\Python\\python.exe', './hg', '--traceback', 'serve', '-n', 'test', '-p', '20070', '-d', '--pid-file=hg.pid', '-E', 'errors.log', '--daemon-pipefds=c:\\tmp\\hg-service-r3tnre']
>
> Similar to:
>
> $ python hg.py --traceback serve -n test -p 20070 -d --pid-file=hg.pid -E errors.log
> calling spawndetached(): ['c:\\Python\\python.exe', 'hg.py', '--traceback', 'serve', '-n', 'test', '-p', '20070', '-d', '--pid-file=hg.pid', '-E', 'errors.log', '--daemon-pipefds=c:\\tmp\\hg-service-x8rclt']
>
>
> So, for the hg.exe case, we have something unusual: The first arg is not the python interpreter, but the hg.exe. The second arg is the hg.py python script. But running 'hg.exe hg.py' obviously doesn't work:
>
> $ hg.exe hg.py version
> hg: unknown command 'hg.py'
I did some wild experimental exemaker hacking (yikes!).
I simulated a frozen exe:
diff --git a/exemaker.c b/exemaker.c
--- a/exemaker.c
+++ b/exemaker.c
@@ -120,7 +120,9 @@
const char bang_python[] = "#!python.exe";
const char lib_os_py[] = "\\lib\\os.py";
const char cannot_find_dll_in[] = "Cannot find DLL in ";
+const char Py_Initialize_str[] = "Py_Initialize";
const char Py_Main_str[] = "Py_Main";
+const char PyRun_SimpleString_str[] = "PyRun_SimpleString";
int __cdecl
main(int ac, char **av)
@@ -128,8 +130,10 @@
HINSTANCE mainDll;
DWORD n;
char* argv[100];
+ void (__cdecl * Py_Initialize)();
int (__cdecl * Py_Main)(int argc, char *argv[]);
void (__cdecl * Py_SetPythonHome)(char* home);
+ int (__cdecl * PyRun_SimpleString)(const char* command);
char fullfile[512];
char workingdir[512];
char requestedapplication[256];
@@ -239,12 +243,27 @@
}
/* get entry points */
+
+ Py_Initialize = (void*) GetProcAddress(mainDll, Py_Initialize_str);
+ if (!Py_Initialize) {
+ strncpy_s(message, sizeof message, cannot_find, sizeof cannot_find);
+ strcat_s(message, sizeof message, Py_Initialize_str);
+ goto error;
+ }
+
Py_Main = (void*) GetProcAddress(mainDll, Py_Main_str);
if (!Py_Main) {
strncpy_s(message, sizeof message, cannot_find, sizeof cannot_find);
strcat_s(message, sizeof message, Py_Main_str);
goto error;
}
+
+ PyRun_SimpleString = (void*) GetProcAddress(mainDll, PyRun_SimpleString_str);
+ if (!PyRun_SimpleString) {
+ strncpy_s(message, sizeof message, cannot_find, sizeof cannot_find);
+ strcat_s(message, sizeof message, PyRun_SimpleString_str);
+ goto error;
+ }
/* get paths */
GetModuleFileName(mainDll, exefile, sizeof(exefile));
@@ -279,6 +298,9 @@
SetEnvironmentVariable("PYTHONPATH", NULL);
SetEnvironmentVariable("PYTHONVERBOSE", NULL);
+ Py_Initialize();
+ PyRun_SimpleString("import sys; sys.frozen=True\n");
+
argv[0] = exefile;
argv[1] = "-S"; /* don't import site just yet */
argv[2] = scriptfile;
This fixes the "hg serve -d" call itself, but causes some other collateral damage,
presumably due to the fact that it's a lie elsewhere that we are frozen.
It seems that the templater notices the lie:
+ $ cat errors.log
+ 127.0.0.1 - - [22/Jun/2012 17:21:02] Exception happened during processing request '/file':
+ Traceback (most recent call last):
+ File "C:\Users\adi\hgrepos\hg-main\mercurial\hgweb\server.py", line 77, in do_POST
+ self.do_write()
+ File "C:\Users\adi\hgrepos\hg-main\mercurial\hgweb\server.py", line 70, in do_write
+ self.do_hgweb()
+ File "C:\Users\adi\hgrepos\hg-main\mercurial\hgweb\server.py", line 137, in do_hgweb
+ for chunk in self.server.application(env, self._start_response):
+ File "C:\Users\adi\hgrepos\hg-main\mercurial\hgweb\hgweb_mod.py", line 92, in __call__
+ return self.run_wsgi(req)
+ File "C:\Users\adi\hgrepos\hg-main\mercurial\hgweb\hgweb_mod.py", line 181, in run_wsgi
+ tmpl = self.templater(req)
+ File "C:\Users\adi\hgrepos\hg-main\mercurial\hgweb\hgweb_mod.py", line 264, in templater
+ style, mapfile = templater.stylemap(styles, self.templatepath)
+ File "C:\Users\adi\hgrepos\hg-main\mercurial\templater.py", line 392, in stylemap
+ raise RuntimeError("No hgweb templates found in %r" % paths)
+ RuntimeError: No hgweb templates found in []
More information about the Mercurial-devel
mailing list