26号,换了CPU和主板显卡等后,启动系统,居然直接圆满进入.
原是P4+845,现为E6300+965,没有传说中的蓝屏,剧烈怀疑是不是此系统认错了我的RP.
然后29号下午说要写一个客户端&服务端的小游戏来当作投职的作品,打开Delphi却报dclite60.bpl加载出错.
然后使用了几分钟,发现工程属性无法设置,点击Options后没有反应.
马上新建一个空工程,点击属性,报告12F9DB,12FB27执行错误.
搜索一下dclite60 access violation未果,马上着手重装D6.
D6重装后,没有任何插件的情况下和去掉所有Package情况下,也还是报同样错误.
六点左右做了备份,开始打算重装系统.
不过系统是在扩展卡上的硬盘,升级还是和往常一样停滞在安装设备的进度上,就跟对面的兄弟去讨论他的表结构若干小时.
然后回来全新安装了系统,安装了驱动,可谓是一步一备份,然后安装D6后,同样的报错嗷嗷叫的打击了我….
这下操作系统问题暂时不考虑了,开始一个一个卸载驱动,结果还是报错,然后使用OllyDbg调试时候,发现12C000属于主程序的线程,怀疑是不是传说中的超线程设置,又顺带进入BIOS,当然扣肉是木有超线程的设置项的,暂且关闭了VT,无效,然后顺着VT往下找时候,一个诡异的No-Execute Memory Protect选项刺眼的Enabled着.这个不就是传说中的DEP状物体么?
怒而关掉后,风平浪静,D6不再嗷嗷叫.
遂恢复昨天系统,打开IE,写下此文,以祭奠我被扣肉吃掉的十个小时….
Archive for August, 2006
近来看统计的Reference,总有搜oracle/oci等误入此窝的.
为了假装此窝,顺便再贴一个和老旧服务器相关的故事.
使用ODAC9/10来代替Oracle客户端部署应用,相对于使用Instant Client的要啥没啥(没有OLEDB,而且居然没Home)的不便,同时相对于Oracle Client牵葫芦带瓢的不爽,是个很好的均衡方案.
ODAC里面附带的OLE Provider是OraOLEDB.Oracle.1,相对于微软的MSDAORA来说,前者的性能较优,而且后者在BLOB等存取中还存在已知问题,使用OLEDB连接Oracle的程序员很多使用此Provider,但总有写程序的人通过其他类库用OLEDB,或者在程序内使用立即字符串MSDAORA来合成连接字串,而不是在配置中指定Provider.
那么问题来了,通常这类程序喜欢华丽地扔出一个80004005的错误,05年我遇见这个时候(某次自定义安装客户端,只选了OLEDB和配置程序),因为看到出错信息里面是提到没有从Oracle返回具体错误类型,就想当然认为不是Provider初始化失败,而以为那几个程序不使用OLEDB,重新将客户端典型安装了事.
等我发现除了原装的Oracle OLEDB Privider,系统中居然还有一个MSDAORA,已经是一年以后的事情了,这个Privider是基于MSDTC的配置,依赖于oracle 8的dll模块,要么是给他提供8的dll(客户端好像有DTC项),要么是让其使用当前Oracle版本的dll,参考的数据是M$的文档,头条就是此问题.
http://msdn2.microsoft.com/en-us/library/ms152516.aspx
做如下修改:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSDTC\MTxOCI
OracleOciLib = oci.dll
OracleSqlLib = orasql9.dll
OracleXaLib = oraclient9.dll
我的数据库服务器只能装9,所以网站和应用服务器上装的是ODAC 92070,这样修改后,不用安装9201客户端,MSDAORA就可以使用了.
此类问题特征: 在Microsoft OLE Provider for Oracle里面,测试连接失败,此为充分条件
使用LordPE或者PETools等查看模块的工具,查看其中加载了oledb32.dll,此为使用了OLEDB的程序,此为必要条件;如果又有msado15.dll,则为通过ado使用OLEDB的程序.
然后使用UltraEdit打开程序查找MSDAORA,为不充分条件.
至此启动此程序,会光荣的报错,可服上剂.
近来尝试将服务器迁移到PHP 5+MySQL5,
发现PHP 5.1.4里面的php_oci8.dll无法加载.
打开display_startup_errors选项后提示无法加载php_oci8,找不到指定模块.
在另一台安装了10g客户端的机器上是可以的.
后来用老办法,对比导入表和导出表,发现是php_oci8使用了9i和8i的oci不支持的OCILobRead2函数.
因为5.1.2的oci8是正常的,马上冲去php的bug tracker网站报告问题,结果被告知这设计就是依赖于10,原因是他们认为在工作于8i兼容模式和让用户下载10的InstantClient两种取舍之间,选择了后者.
于是我很郁闷,我就回复说我服务器本身有Oracle 9i服务端,服务端自身带的有oci,安上InstantClient后混用的问题一堆,(05年就郁闷了我大量的时间),不可能为了你PHP而崩掉其他用OLE/ODBC/Client的程序或者升级oracle服务端(服务器烂,升过10g跑不动),同时因为这个只是php_oci8用到的66个函数里面(9i OCI有六百多个函数),只用了1个依赖于10的函数,要说是为了工作于大于4G的2模式,为何别的函数都没动,然后怀疑他们先搞坏了再建议用户用10,结果被鄙视了,月我们已经解释完了你可以走了.
在报告bug前,尝试编译php_oci8出错,我用了一个Q&D的方法,用LordPE修改了导入表,当然这个LobRead和LobRead2中间的回调函数的参数个数不一样的,这样做只是让Windows成功载入oci8,报告bug后我很郁闷打算自己来解决,重新看了下514的代码,原来是514的dsp工程里面遗留了php4ts作为库导入,改为php5ts后,用9的include编译通过.
我认为这个问题发生的原因就是PHP的php_oci8.dll是使用导入表来使用oci.dll,因为php_oci8.dll不是独立的进程,那么他也就依赖PELoader用宿主w3wp/inetinfo调用oci.dll,也就是一切看当前的环境变量了.
经过分析,10g的oci.dll不再加载其他oracle的dll文件,那么按照宿主进程当前目录优先的规律,将其放置入windows\system32\inetsrv文件夹,然后用进程查看工具,dllhost,msdtc和其他程序调用的oci是系统里的9i目录中的,而w3wp/inetinfo使用的是其目录下的10g的oci.dll,这个dll因为不在系统path中,也不会被IIS以外的程序使用.
这个解决应该是既不用用9来编译,而且不会引起系统的版本冲突的办法了.
进一步,使用LoadLibrary来处理用到的每个函数地址,取代使用导入表硬性引用方式,应该可以起到相等于oci.so的作用.
更进一步,在PE级别对2个dll进行合并(以前成功进行过这种疯狂操作),或者说从dll得到静态lib,编译出不需oci.dll的php_oci8.dll,好像会更加的解恨.