创建共享内存时出错

时间:2013-04-09 19:17:27

标签: delphi

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

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

  

第一次机会异常,价格为753CB9BC。异常类Exception with   message'创建共享内存时出错   全球\ {B40FBC0C-FEBD-11DD-B3EA-FC6656D89593}(5)'。处理   OrderCenter.exe(836268)

我甚至无法一步一步地运行软件,它似乎发生在我进入运行应用程序本身之前。我不知道如何解决这个错误,我肯定可以查看代码并理解它并可能修改它但我肯定根本不理解如何修复错误,如没有任何关于谷歌的文档< / strong>即可。我尝试浏览谷歌和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

如果,我试着看一下这段代码的声明,看来它确实试图创建一个全局共享内存对象,可能是某种Mutex,以防止双重初始化。

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

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

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

2 个答案:

答案 0 :(得分:15)

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

  

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

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

首先,异常类是Exception。据我所知,RTL或任何声誉良好的第三方库中没有任何内容引发类Exception的例外。这被认为是不好的做法。始终提出Exception的子类。你的应用程序代码提出了这个例外。

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

最后,该消息包含通过调用GetLastError检索到的Win32错误代码。该代码为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]
  );

这就是我所能提供的证据。但现在您知道在程序中搜索什么以找到失败的代码。给你。

答案 1 :(得分:0)

我发布了这个答案,因为对问题的编辑使得很难理解历史。向大卫提示,了解异常消息的含义而不看代码,并向块上的新人解释OP。

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

这个死亡的代码很可能是一个元素:

(a)从普通德尔菲技术的一些食谱中复制并粘贴,或

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

这段代码可能会因为在1998年在Windows NT上移动为例如Delphi 5编写的组件代码而导致错误,因此它不再在Verphi 7或8上的Delphi XE3中运行。 这种现象并不是德尔福独有的,被称为“比特腐烂”。换句话说,环境是一个移动目标,旧代码经常像这样打破。在不了解Delphi或PHP程序员所涉及的Win32 API的情况下解决这个问题,就像让汽车修理工对我的肝脏进行手术一样。我不会给这个家伙赔率。

然而,这是一个计划:

一个。评论它。

B中。继续测试!

嘿嘿哇哇哇哇哇哇哇哇哇哇哇哇哇哇! ; - )