Honeybee Components Crash Rhino Immediately (Python uuid dependency seems suspect)

I have a plethora of errors in the past few days trying to revive a script. The major issue I am facing is that it seems any time a Honeybee component is attempting to load, it crashes Rhino/Grasshopper without any error log. One thing I found by locking the script containing legacy Honeybee components (and a healthy amount of research and troubleshooting) I noticed the crash always seems to involve components containing code for setting unique uids. (i.e. import uuid) Every single one of those components causes the crash as soon as it hits an unlocked canvas. Commenting out the line while the script is locked allows the component to exist on the canvas, and run, but without any of the dependencies to uuid.

Now, it gets a bit more interesting. To try troubleshooting further, I reinstalled nearly everything except Rhino. Same issue. I also downloaded LBT 1.1.0 to see if something stood out to me, which opened up a number of issues/trials to get those components to load, which I think I have gotten past most of including the issue of having to manually set the site_packages directory in Rhino (as I do have a company managed workstation). The interesting part is that after getting to the point where everything should be operational, I began to notice some of the Honeybee components of LBT 1.1.0 also immediately crash Rhino similar to the legacy crash I describe above.

So this is where I’m currently stuck. Is this an issue anyone has experienced? It seems like something is possibly wrong about the Python installations, which I attempted total re-installs. No change, and all other Python scripts I am using appear to work fine before and after. Or is this particular issue possibly due to a firewall program? (The company employs Sentinel which I saw a horror story about in another forum, and Grasshopper component folders had to be unprotected.) If that’s this issue, I have no management over that tool whatsoever.

1 Like

Can you try to import uuid and create one in a separate GHPython component?

When you say you updated the Python installation do you mean the IronPython that comes with Rhino? That’s the one that’s loaded in the components. Try this code:

import uuid
print uuid.__file__

import uuid definitely crashes Rhino in a Python component. I have a few versions of python installed, but not IronPython. Perhaps just reinstalling IP 2.7.6 or 2.7.7 may fix this. I’m going to try a full reinstall of Rhino. Will check in this evening.

Great to hear from you, Mostapha.

Reinstalling did not seem to help. It left my AppData and preferences in tact, so that could still be a concern. Also, I had installed IronPython separately, I have now uninstalled to avoid conflicts with the IronPython installed for Rhino/Grasshopper, but maybe it hasn’t been entirely uninstalled. I do have Python 2.7.18 separately installed for other applications.

It’s the exact same issue however. import uuid alone in a script causes an exit. I tried checking sys.version inside a GHpy component which returns 2.7.8 (IronPython 2.7.8 (2.7.8.0) on .NET 4.0.30319.42000 (64-bit))

With my work environment using Sentinel Agent, this post seems relevant.
https://discourse.ladybug.tools/t/updated-honeybee-freezes-and-crashes-rhino/8058/6

@wim, do you know why this might be happening?

@Paul1, it’s an issue with the IronPython installation that comes with Rhino installation. Updating Rhino to the latest version should fix the issue .

@mostapha After updating to the latest stable & service release candidate, I can confirm the IronPython issue with calling uuid is still present. Maybe the registry needs keys cleaned before a reinstall. Should I log a ticket on the McNeel discourse?

@Paul1 ,

Can you confirm whether you are running Rhino 6 or Rhino 7? And also what Service Release is the latest one that you are using?

@chris , it’s Rhino 6.31.20312.17001 currently.

Thanks, @Paul1 .

This seems like it’s probably because you have some other IronPython installed on your machine, such as an IronPython for Revit/Dynamo, that is conflicting with your Rhino IronPython. This issue may be of help in debugging:

In any case, a bug in the IronPython that’s loaded by Rhino/Grasshopper is a bit beyond our expertise to help and you’ll need someone like @wim or @eirannejad to help. Or you could post the issue to the McNeel forum to see if you can get someone there to help.

2 Likes

@chris @Paul1
The uuid module uses kernel functions (similar to cryptographic functions). So import uuid eventually reaches inside system native modules to call the uuid generator. Seems like in some cases a System.AccessViolationException exception is thrown (usually a bad pointer in the native code) and it crashes the running application. In this case it seems the exception is thrown while loading the native module that contains the uuid generator.

We had this issue with pyRevit back in 2018. Gui Talarico debugged and figured it was the import uuid that was causing the exception and crash.

We solved the problem by directly accessing the uuid generator in the .NET framework instead, so I never looked deeper into the issue.

I can take a look tomorrow and see if we can find the root cause.

3 Likes

Thank you for the detailed explanation, @eirannejad .

Gui’s link to the native .NET workaround seems to be broken on the Github issue but, even with this, it would be pretty difficult for us to remove all of the places where we use uuid in Ladybug Tools, particularly because our core libraries use it and they are written to work in both IronPython and cPython 3.7. So it’s not impossible but it would make our code a lot messier as we’ll need to add a bunch of try/excepts in the core libraries to catch the case that we’re in a non-compatible version of IronPython.

Please keep us posted if you identify the underlying cause and let us know if there’s anything we can do to help or test.

@chris
Let’s run this in Rhino python editor and see how many IronStuff are loaded first

from System import AppDomain

print("Name,Version,Location")
for loaded_assembly in AppDomain.CurrentDomain.GetAssemblies():
    try:
        loc = loaded_assembly.Location
    except:
        pass
    if str(loaded_assembly.GetName()).startswith('Iron'):
	    print(
	        "{0},{1},{2}".format(
	            loaded_assembly.GetName().Name,
	            str(loaded_assembly.GetName().Version),
	            loc,
	        )
	    )

On my machine

Name,Version,Location
IronPython,2.7.9.0,C:\Program Files\Rhino 7\Plug-ins\IronPython\IronPython.dll
IronPython.Modules,2.7.9.0,C:\Program Files\Rhino 7\Plug-ins\IronPython\IronPython.Modules.dll
IronPython.Modules.DynamicAssembly,0.0.0.0,C:\Program Files\Rhino 7\Plug-ins\IronPython\ICSharpCode.TextEditor.dll
1 Like

@eirannejad

I ran that code on the problematic machine finding that there is no entry for Dynamic Assemblies. That’s primarily a .Net interface isn’t it?

Name,Version,Location
IronPython,2.7.8.0,C:\Program Files\Rhino 6\Plug-ins\IronPython\IronPython.dll
IronPython.Modules,2.7.8.0,C:\Program Files\Rhino 6\Plug-ins\IronPython\IronPython.Modules.dll

Nah I think that assembly is generated dyanically by the python code editor window. My test was from Rhino 7 (that I think might use a different editor or have more functionality). Rhino 6 reports the same as yours

Name,Version,Location
IronPython,2.7.8.0,C:\Program Files\Rhino 6\Plug-ins\IronPython\IronPython.dll
IronPython.Modules,2.7.8.0,C:\Program Files\Rhino 6\Plug-ins\IronPython\IronPython.Modules.dll

@Paul1 Okay let’s try running this now and see the output

import ctypes
print ctypes.util.find_library('rpcrt4')

_UuidCreate = None
try:
    import ctypes, ctypes.util
    import sys, os

    try:
        lib = ctypes.windll.rpcrt4
        print lib
    except:
        lib = None
    _UuidCreate = getattr(lib, 'UuidCreateSequential', getattr(lib, 'UuidCreate', None))
except Exception as ex:
    print(str(ex))
C:\WINDOWS\system32\rpcrt4.dll
<WinDLL 'rpcrt4', handle db830000 at 6c>

@eirannejad

On the problem machine that code returns the following error. The temp file does exist containing a copy of the script entered into the Rhino Python Editor.

Message: ‘module’ object has no attribute ‘util’
Traceback:
line 2, in , “C:\Users\PDrake\AppData\Local\Temp\TempScript.py”

On a machine able to use uuid, I get info similar to your’s.

C:\windows\system32\rpcrt4.dll
<WinDLL ‘rpcrt4’, handle fd0c0000 at 4ab9c>

@Paul1 Okay try this now (added an extra line from ctypes.util import find_library to avoid the module error)

import ctypes
from ctypes.util import find_library
print find_library('rpcrt4')

_UuidCreate = None
try:
    import ctypes, ctypes.util
    import sys, os

    try:
        lib = ctypes.windll.rpcrt4
        print lib
    except:
        lib = None
    _UuidCreate = getattr(lib, 'UuidCreateSequential', getattr(lib, 'UuidCreate', None))
except Exception as ex:
    print(str(ex))

@eirannejad
Thanks for updating - that does load ctypes and outputs the library location correctly:

C:\WINDOWS\system32\rpcrt4.dll
<WinDLL ‘rpcrt4’, handle c9d70000 at 6c>

Odd. Okay open this file, copy the contents and run in the python editor please:
C:\Program Files\Rhino 6\Plug-ins\IronPython\Lib\uuid.py

If this doesn’t cause a crash, then we need to dig a lot deeper and I’ll probably need some sort of access to the bad machine. Maybe we can use TeamViewer

Running the script directly in the Python editor does crash Rhino all the same as importing uuid.

I’ll try commenting some out to see if I can narrow down why.