-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Embedded NULL failure #36
Comments
This was a Python bug that's been fixed in both CPython and Fbuild. I'll put the fix in Felix's copy later! |
I tried the code in fbuild. That fails too! Using this:
I get
I also tried that latest fbuild as a whole, and that fails much earlier What bothers me is that this all worked until the latest major commit. https://ci.appveyor.com/project/skaller/felix/history The winprocess.py code has not changed. Interscript was removed. |
You mixed up the fix a bit... It should be LPCSTR, not LPCWSTR. AppVeyor's Python likely got upgraded to a version that has the bug. |
Ooops...:-) Thanks! Will report back. I'm using Python 3.5 on Appveyor. |
Well with the fbuild version I now get this:
|
Help!! :) |
@skaller Ahhhhh I hate Windows's Unicode handling. 😠 Try this:
Notice the change from |
The problem is Python, not Windows :) Error checking text strictly is a stupid default. |
Well that fixed the problem I think but now there's another one: https://ci.appveyor.com/project/skaller/felix/build/1.0.1638
The compiler found appears wrong .. it should be the full 64 bit compiler but isn't. |
@skaller Can you have AppVeyor |
I'm not sure how to do that. However I can run on my Windows box. But I am guessing the problem is in the Python interface. Windows works JUST FINE with 8 bit data. Felix can do things in windows with popen emulation. Why the Python code tries to complex and irrelevant UTF-16 encode/decode crap i don't know. I am guessing the "null" byte in the string is there because in fact the string is a bad attempt to create main's argv which is an array or null terminates strings. |
OK so on my windows box:
Now, I tried this manually:
which shows cl.exe is there and it works fine. The shown command with arguments does NOT work, the quoting is all wrong. So the problem is bad quoting. |
So .. FYI in https://github.com/felix-lang/felix/blob/master/src/packages/program.fdoc you will find around line 1018 the rules for quoting on Windows for CMD.EXE. Roughly it is appears simple enough:
and the base type class says:
In other words you just put "" around each argument, separate them by a space, and then quote the whole string again with "". If you have sloshes in the arguments DO NOT DOUBLE THEM UP. you do have to double up the sloshes in C or Felix string literals because the language lexer will replace them but not if you're constructing the strings. Not sure if this helps. It took Shayne Fletcher and myself about 6 months working over Facebook with me on OSX and him on Windows to get this to actually work. It looks and is simple but it took a long time to figure out the rules. What you type at a CMD.EXE prompt is NOT the same as what you supply to system() or popen() the latter require the extra quote of the whole string. |
BTW: on windows the problem is that programs do NOT get separate arguments as they do on Unix. On WIndows, which used to be MSDOS, programs get a single string and have to parse the string themselves. What happens is in CMD.EXE, it finds the program name and calls it passing the WHOLE string to it. Now C programs requires main(argc, argv) so the startup code for C has the command line parsing it it. This ONLY applies to console programs! Similarly stdin/stdout are connected to the console in the startup code. So when you call system() or popen() they start a CMD.EXE instance and pass to it the string argument WITH THE WRAPPER QUOTES REMOVED. So the string you use is not the same as when using the CMD.EXE prompt! The the C startup quote parses that to find the argv arguments, again stripping out the argument quotes if present. The tricky bit is that the whole string quote marks are removed, so if they're not there and the first argument is quoted .. the ARGUMENT quote is removed by mistake, and the end of argument quote then quotes the rest of the string by mistake and so it gets treated as a single argument! Or something like that. Its a mess. The problem is Unix and C. What MSDOS did was actually more sensible. Actually if you glob commands to CMD.EXE it does nothing: the program has to decode the globs. In Unix shells the shell decodes the globs. In Felix this is a right pain because I had to pick whether globs are unpacked or not because there is only ONE "system()" method and you really need two, not just for globs but other shell expansions. In Unix it depends on how you do the quoting whether the the shell expands the argument or not: double quoted arguments are expanded, single quoted ones aren't. Its a pain because of multiple layers of quote stripping. Its a pain in plain bash for the same reason. You have to calculate how many levels of (double up) quotes you need based on how many quote stripping passes you go through because you actually dispatch to the process you want (since the shell can contains, say, parens which spawn sub-shells ... ARGGGH) :) |
The Python code uses CreateProcessW (the wide-char) version. Not exactly sure why, but the original Mozilla killableprocess code was like that. A quoting issue is actually odd. Python should properly quote it, and the quoting issue is probably just from printing it... The test tries compiling an actual C program. Could be an environment issue or something. I. Really. Hate. Killableprocess.py. |
The diagnostic when the compiler is invoked by hand says the file can't be found, because its a temporary already gone. In other words .. the command works fine when i use it manually with the correct quoting. So its not an environment issue uinless the process is started without inheriting the environment. The build system is run in a terminal with MSVC already set up. The thing is .. the original code USED TO WORK. It just died somehow for no apparent reason .. I switched from VS2015 to VS 2017 in Appveyor but not on my local Windows box and it fails there the same way. |
Ok so I fixed it. Here's how: I DELETED fbuild's subprocess directory and changed the reference Lo, it works. On OSX and on WIndows and hopefully Linux. It seems that the fbuild subprocess was added so that a broken version of Python |
Building Felix:
I haven't seen this before, I have changed the build process a bit.
It looks like a bug in Python.. but why didn't it happen before?
Appveyor CI:
etermining platform : {'windows', 'win32'}
looking for cl.exe : ok C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\amd64\cl.exe
checking cl.exe : Traceback (most recent call last):
File "fbuild\fbuild-light", line 11, in
main()
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\main.py", line 179, in main
result = build(ctx)
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\main.py", line 104, in build
target.function(ctx)
File "C:\projects\felix-e3h83\fbuildroot.py", line 585, in build
phases = configure(ctx)
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\db_init_.py", line 121, in call
result, srcs, dsts = self.call(*args, **kwargs)
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\db_init_.py", line 125, in call
return ctx.db.call(self.function, ctx, *args, **kwargs)
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\db\database.py", line 165, in call
call_result = function(*args, **kwargs)
File "C:\projects\felix-e3h83\fbuildroot.py", line 558, in configure
build = config_build(ctx)
File "C:\projects\felix-e3h83\fbuildroot.py", line 328, in config_build
flags=ctx.options.build_c_flags),
File "C:\projects\felix-e3h83\fbuildroot.py", line 258, in make_c_builder
static=call('fbuild.builders.c.guess_static', ctx, *args, **kwargs),
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\functools.py", line 32, in call
return import_function(function)(*args, **kwargs)
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\builders\c_init_.py", line 457, in guess_static
), *args, **kwargs)
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\builders\c_init_.py", line 394, in guess_builder
return fbuild.functools.call(function, ctx, exe, *args, **new_kwargs)
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\functools.py", line 32, in call
return import_function(function)(*args, **kwargs)
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\builders\c\msvc.py", line 531, in static
compiler=Compiler(ctx, Cl(ctx, **kwargs),
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\db_init.py", line 68, in call
*args, **kwargs)
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\db\database.py", line 165, in call
call_result = function(*args, **kwargs)
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\db_init_.py", line 64, in call_super
return super().call(*args, **kwargs)
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\builders\c\msvc.py", line 38, in init
if not self.check_flags(flags):
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\builders\c\msvc.py", line 116, in check_flags
self([src], flags=flags, quieter=1, cwd=src.parent)
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\builders\c\msvc.py", line 103, in call
return self.ctx.execute(cmd, msg2=msg2, **kwargs)
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\context.py", line 214, in execute
**kwargs)
File "C:\Python35-x64\lib\subprocess.py", line 676, in init
restore_signals, start_new_session)
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\subprocess\killableprocess.py", line 182, in _execute_child
winprocess.EnvironmentBlock(env),
File "C:\projects\felix-e3h83\fbuild\lib\fbuild\subprocess\winprocess.py", line 129, in init
self.as_parameter = LPCWSTR("\0".join(values))
ValueError: embedded null character
NMAKE : fatal error U1077: 'C:\Python35-x64\python.EXE' : return code '0x1'
Stop.
The text was updated successfully, but these errors were encountered: