如何摆脱VW 3.1d和ENVY中的非托管代码

时间:2009-09-07 16:09:31

标签: smalltalk visualworks

我有一个旧的VW3 / ENVY图像,其中包裹作为非托管代码加载(确切情况Mastering ENVY/DEVELOPER警告)。不幸的是,这个问题发生在很久以前,如果没有加载包裹就“回到”图像为时已晚。

显然,有一种方法可以解决这个问题(我们有一个开发图像已经解决了这个问题,并且有一些普通的配置图包含与非托管包裹完全相同的代码,但它们无法加载),但确切的方式早已被遗忘(并且将特定的dev图像作为新运行时图像的基础存在一些问题,因此我需要了解如何再次执行此操作)。

理论上,应该可以删除宗地并从配置图重新加载代码。实际上,所有正常方式(使用ParcelBrowser或直接调用UnmanagedCode>>删除)都会失败。我甚至尝试从方法字典中手动删除有问题的选择器,但是经过某一点(涉及调用#primBecome :),整个图像完全挂起(我甚至无法进入调试器)。我开始攻击类和方法的实例,希望我能让ENVY认为这些特定方法是正常的版本化代码,但还没有任何成功。

周围是否还有任何关于VW 3的小型/嫉妒大师能给我提供任何指示?

状态更新 经过一个星期的尝试解决问题,我终于做到了,至少部分,所以万一有人感兴趣......

首先,我必须修复umnanaged代码的文件指针(否则,所有试图触及方法的东西都会引发异常)。看起来ENVY扩展了Parcel,理论上,所有整数文件指针在加载时都会更改为ENVY的void文件指针,但在我的情况下,我必须手动执行(Parcel为它定义的所有选择器提供枚举) )。另一种方法是调整filePointer代码,但不能在需要的每个图像上自动完成。

然后,可以丢弃包裹,这会丢弃宗地信息,但会保留代码。官方的“弃牌”机制需要有一个有效的更改文件(嫉妒不使用,因此必须手动设置,然后重置)和包裹源(我们幸运的是)。

为了能够对方法进行任何更改(手动或通过从ENVY加载应用程序或类),他们需要摆脱他们的非托管状态。这可以通过手动调整TheClass>>applicationAssocs来完成(我还删除了对UnmanagedCode sich中的类的所有引用作为时间戳,并删除了对丢弃的parcel的引用)。我实际上有一些关于如何从我的老板那里得到这一点的信息,但是在我几乎把它弄清楚之前我一直无法理解这些说明。

这最终允许我加载并重新加载包含这些类的所有应用程序。理论上。实际上,每当我尝试加载较新版本的应用程序(包含以前在包裹中的代码)时,图像仍然完全挂起。

事实证明,崩溃绝对与非托管代码无关,但事实是有问题的地块修改了InputState>>process:,导致了由于缺少和/或未初始化的类变量(直到新InputState>>initialize方法到位后才调用process:方法)。我不得不修改Notifier类来转储文件的所有异常,以找出发生了什么。将类变量添加到类的源代码(而不是通过反射添加它),通过toBeLoadedCode挂起输入处理线程并在loaded方法中再次启动并创建应用程序的新版本甚至解决了这个问题。

现在理论上一切正常。在实践中它仍然无法使用,因为重新加载WindowSystem或VisualworksBase应用程序会导致它们的初始化块运行,并且大量设置被重置为其默认值 - 字体和字体大小,窗口颜色,UI设置......而且没有似乎只是将设置保存到文件并稍后加载它们,或只是为了查看所有设置是什么(官方设置菜单没有显示所有内容,或者我们有一个严重调整的图像...从头开始重建它。但这是一个完全不同的问题。

1 个答案:

答案 0 :(得分:1)

通常,建议您应该能够通过从存储库加载代码来从头开始重建开发映像。但如果你有,那么答案很简单,只需丢弃该图像并重新加载。我认为这已经足够长了,我已经失去了关于如何弄乱内部结构以获得它的任何知识,而且听起来你已经尝试了很多东西。所以,虽然它可能很痛苦,但通过从存储库中加载东西来找出重建开发图像的方法听起来可能是你最好的选择。它可能不是那么可怕,可能只是对图像状态有一些依赖,或者需要执行的特殊操作。

您可能还需要根据您正在处理的图像中的内容验证存储库中的内容。如果加载了非托管代码,然后有人对其进行了修改并保存,那么我不清楚它是否会保存到ENVY中。因此,您可能希望审核所有非托管代码,如果已更改,请将其保存到存储库版本。

抱歉,我没有更好的答案。