Sublime Forum

Ctypes from sublime text 3 python broken on windows

#21

Additionally, I noticed when loading it via Sublime Text that a console window flashes onto the screen briefly.

0 Likes

#22

You just had a bug at https://github.com/niosus/test-complete-plugin/blob/master/script.py#L13, it should have been:

filename = path.abspath(path.dirname(__file__) + "/test.cpp")

This works fine for me on Windows 10 x64 with build 3120 and Clang 3.8.1.

2 Likes

#23

uh, embarrassing as it is, you are totally right. It works for me too. A reminder to have no relative paths. Thanks a lot!

0 Likes

#24

This is because there is a subprocess spawned and on windows it flashes a cmd window.

0 Likes

#25

So what does that prove if test works? Is it too minimalistic to expose the bug? I assume main plugin still doesnā€™t work?

There is a way to suppress that but I guess that is least of a problem right now.

0 Likes

#26

I believe it shows that there isnā€™t a problem with ctypes within Sublime Text, in the general sense.

A further data point is that Package Control has used ctypes on Windows for quite a while to integrate with WinINet and the system trust store. I imagine there are various bugs with Python 3.3 on Windows, but in the general sense ctypes seems to work fine from within Sublime Text.

If anyone has examples of ctypes working outside of Sublime Text, but not within, I can certainly try to look at them.

0 Likes

#27

Could you please try the updated script from this repo?
There still seems to be a problem that only occurs from Sublime Text.

When I run the script from Power Shell (also from some other folder apart from Packages folder) it works as expected. It parses some c++ code, reparses it, completes it couple of times and then prints some error statistics, which are in this configuration plenty.

When you run it as a plugin of sublime text it crashes the plugin_host. @wbond could you try to run it with your custom version of python to narrow down the reason for this behavior? Thanks!

Yep, this is definitely not the biggest problem for now. I am sure that there is a way, but first it has to work :slightly_smiling:

0 Likes

#28

Hello @wbond. Have you had the time to run the script in the repo? It is really interesting if it crashes also if you run it with the custom python from the powershell.

Hope you have time for this. Thanks anyway!

0 Likes

#29

Iā€™ve been analyzing this a bit with custom debug build of clang and while I donā€™t have any conclusive results, I see one problem at least, I think.

cindex38.py has a class like that:

class File(ClangObject):
    """
    The File class represents a particular source file that is part of a
    translation unit.
    """

    @property
    def name(self):
        """Return the complete file and path name of the file."""
        return conf.lib.clang_getCString(conf.lib.clang_getFileName(self)).decode('utf-8')

    def __str__(self):
        return self.name

    def __repr__(self):
        return "<File: %s>" % (self.name)

Now, getting the name property of the File instance, passes self to clang API. It seems like in Sublimeā€™s Python this triggers __repr__ on the instance, which accesses self.name again, causing infinite loop and stack overflow.
That must happen inside Ctypes as I canā€™t see that loop happening when adding printā€™s in the __repr__. But it works if I donā€™t use self.name in __repr__.

conf.lib.clang_getFileName() implementation in libclang.dll is never called in this case so the infinite loop must trigger before that libclang API is invoked.

I could probably tell much more if I would have sublimeā€™s python3.dll debug build with symbols, but itā€™s probably not an option. I also have custom standalone build of python3 so I could compare code paths easily then.

0 Likes

#30

Actually these are not __str__ or __repr__ that cause this. I got confused with my added debug code. From what I said above, the only true part is that stack overflow is triggered on calling conf.lib.clang_getFileName(self)

0 Likes

#31

The problem is due to something going wrong when passing pointers to the clang API.

Things go wrong when calling clangā€™s clang_getInstantiationLocation API which has this declaration in python bindings:

("clang_getInstantiationLocation",
   [SourceLocation, POINTER(c_object_p), POINTER(c_uint), POINTER(c_uint),
    POINTER(c_uint)]),

In the python code those arguments have these memory locations:

SourceLocation: <cparam 'P' (00000000043CDFD0)>
File: <cparam 'P' (0000000004513990)>
Line : <cparam 'P' (0000000004513790)>
Column: <cparam 'P' (0000000004513690)>
Offset: <cparam 'P' (0000000004513A10)>

While clang code receives those locations:

location = {ptr_data=0x00000000043cdfd0 {0x0000000005ada3c0, 0x000000000037b890} int_data=62 }
file = python33.dll!0x000000001e58afa8 (load symbols for additional information) {0x0000000000000008}
line = 0x00000000044a0ae8 {2}
column = 0x0000000004513990 {0}
offset = 0x0000000004513790 {0}

As can be seen here, only the first and last two arguments point to the correct memory location. Rest are just random memory addresses, one even pointing to the dll code itself so it will corrupt something when clang writes into it.
Worth pointing out that memory locations for fourth and fifth arguments are actually for the second and third argument, so they got shifted right.

I think there is probably a bug in ctypes used by Sublimeā€™s python.

0 Likes

#32

This is most likely the fix for this issue: https://hg.python.org/cpython/rev/f75b0470168b?revcount=120

0 Likes

#33

@wbond, @jps: Will you consider taking that patch into sublimeā€™s python build?

0 Likes

#34

Recently weā€™ve been using 3.3.6 with some changes to get a static lib on OS X and Linux, and changes to get a single .dll on Widows. Weā€™ve also pulled in two Windows unicode patches from 3.4:

These are necessary since unicode support in 3.3 on Windows is incomplete when paths include characters not in the users single-byte locale encoding.

Moving forward, Iā€™ll grab the latest from the 3.3 branch, which includes the patch for structs. 3.3.7 was supposed to be released back in February, and Iā€™ve emailed the release manager, but he said it is held up by ā€œundisclosed security vulnerabilities.ā€ Seems like there isnā€™t much urgency to security issues since it has been six months now with no more updatesā€¦

1 Like

#35

I donā€™t know how itā€™s possible but there is still exactly the same problem in 3121.

0 Likes

#36

The actual fix is actually missing on 3.3 branch. For example all the parts in Modules_ctypes\libffi_msvc\ffi.c are not there.

0 Likes

#37

The patch is on the 3.3 branch. You can see it at https://hg.python.org/cpython/rev/4d33bccb59a8, which is a parent of 8e3b9bf917a7 (used in builds 3121 and 3122).

0 Likes

#38

As weā€™ve discussed in private, those patches are related but not the same. We are still missing the part that was relevant for this issue.

0 Likes

#39

For the record, here are two other patches for Python 3.3 ctypes on Win x64 with MSVC:

0 Likes

#40

As of build 3123 we now have the patches for 64 bit Windows ctypes backported from Python 3.4.

0 Likes