-5

我必须调试一个使用 Delphi CodeGear 2009 构建的应用程序,该应用程序是由我以外的其他人构建的,而这个人不再是公司的一部分。

奇怪的问题,当我将项目加载到代码设备并运行应该实际工作的软件时,我收到一个错误:

第一次机会例外,$753CB9BC。异常类异常,带有消息“创建共享内存时出错 Global\{B40FBC0C-FEBD-11DD-B3EA-FC6656D89593} (5)”。处理 OrderCenter.exe (836268)

我什至无法在逐步模式下运行该软件,它似乎发生在我进入运行的应用程序本身之前。我不知道如何修复这个错误,我当然可以查看代码并理解它,也许可以修改它,但我肯定完全不明白如何在没有任何 google 文档的情况下修复这样的错误。我尝试浏览 google 和 SO 一段时间,尝试各种关键字组合,但没有任何结果。

我该如何调试呢?我从哪里开始寻找?


编辑#1

为了澄清,我什至在进入应用程序之前就遇到了一个异常,它甚至无法调试。我很乐意尽快粘贴堆栈跟踪,以便每个人都可以看到它在哪里崩溃。很抱歉最初没有想到这一点。

我在 Google 上搜索了确切的错误消息,但没有发现任何有用的东西。这里有几个例子:

http://www.google.ca/#hl=fr&output=search&sclient=psy-ab&q=Error+creating+shared+memory&oq=Error+creating+shared+memory

http://www.google.ca/#hl=fr&sclient=psy-ab&q=delphi+Error+creating+shared+memory&oq=delphi+Error+creating+shared+memory


编辑#2

感谢您花时间指定某种初始化程序的人,我在所有文件中搜索并找到该程序并发现代码在这里崩溃:

if not AlreadyRunning(ProcessName, TFormMain, False, False, True) then

如果,我尝试查看这段代码的声明,它似乎确实在尝试创建一个全局共享内存对象,可能是某种互斥锁以防止双重初始化。

我的第一个猜测是,除了用户现在可以运行 2 个以上相同的应用程序这一事实之外,我可能只是放弃这部分代码而不会产生任何直接后果。

在旁注中,我想知道为什么这首先会失败(Win7,管理员帐户)?

PS:我最初无法找到错误发生位置的原因是因为应用程序处于发布模式而不是调试模式,我花了一些时间和深入的 UI 搜索在文件中的构建配置下注意到它经理。没有其他任何迹象表明我处于发布模式,直到我尝试在应用程序的初始化部分放置断点并且它不会停止......

4

2 回答 2

15

该错误是由您的程序专门引发的。从这个消息中可以看出:

异常类异常,带有消息“创建共享内存时出错 Global\{B40FBC0C-FEBD-11DD-B3EA-FC6656D89593} (5)

这具有 Delphi 程序引发的异常的所有特征。十六进制由$而不是表示0x,并且消息的第一个单词是标准的Delphi。我将假设是您的程序引发了此异常。

首先,异常类是Exception. 据我所知,RTL 或任何有信誉的第三方库中都没有引发 class 异常Exception。这被认为是不好的做法。总是提出一个子类Exception。因此,您的应用程序代码正在引发此异常。

其次,消息描述了创建共享内存的错误,并给出了命名空间中的命名对象Global。这可能是一个命名的文件映射对象。

最后,该消息包含一个 Win32 错误代码,该代码通过调用GetLastError. 那个密码是 5 号,我们的老朋友ERROR_ACCESS_DENIED

因此,该程序似乎与一个单独的进程协同运行,并且使用共享内存(文件映射)进行通信。无论出于何种原因,该文件映射的安全性都没有正确设置。

该对象已放置在Global命名空间中,如果您需要在会话之间共享它,您可以这样做。因此,另一个进程驻留在会话 0 中的服务中似乎是合理的。也许尚未正确指定保护对象以进行跨会话访问所需的安全属性。

引发异常的代码看起来有点像这样:

FileMapping := OpenFileMapping(FILE_MAP_READ or FILE_MAP_WRITE, 
  False, PChar(FileMappingName));
if FileMapping=0 then
  raise Exception.CreateFormat(
    'Error creating shared memory %s (%d)',
    [FileMappingName, GetLastError]
  );

这就是我从所提供的证据中所能说的。但是现在您知道要在程序中搜索什么来定位失败的代码了。交给你。

于 2013-04-09T19:49:26.713 回答
0

我发布了这个答案,因为对问题的编辑使人们难以理解历史。向 David 致敬,让他在不看代码的情况下理解异常消息的含义,并向街区的新人 OP 解释这一点。

似乎在 David 的帮助下,您找到了一些防止重复运行的代码实例的代码。如果您删除它,您可能不会受到其他处罚,但由于我们无法读取您的代码,因此我们无法确定地告诉您。我还要指出,发布和调试模式的概念对于本地开发人员(C++ 和 Delphi)来说是显而易见的,而对于那些不熟悉编译器和本地代码的人来说,可能更加微妙。如果您要维护一个 Delphi 应用程序,可能值得买一本关于 Delphi 的书。如果这是您的第一个编译/本机语言,那里有更多的龙,而且水很快就会变深。

这段即将死去的代码很可能是一个元素,它是:

(a) 从一些常见的德尔福技术食谱中复制和粘贴,或

(b) 甚至不是由原作者编写的组件或类的一部分

这段代码可能会因为移动这个为 1998 年的 Delphi 5 编写的组件代码而在 Windows NT 上产生错误,因此它在 WINdows 7 或 8 上的 Delphi XE3 中不再起作用。这种现象并非 delphi 独有并被称为“位腐烂”。换句话说,环境有点像一个移动的目标,旧代码经常这样中断。由 PHP 程序员在不了解 Delphi 或涉及的 Win32 API 的情况下解决此问题,就像让汽车修理师在我的肝脏上做手术一样。我不会给这家伙赔率。

不过这里有一个计划:

A. 把它注释掉。

B. 继续测试!

嘿抱歉狙击你,现在我们平了!;-)

于 2013-04-10T13:58:58.930 回答