源代码一人一份,我们才能分析。byte 码谁能看懂.
解决方案 »
- 都来看看啊。长见识的时候到了(里面还藏有一个帖子,分多多)
- VC++ 怎样获取硬盘的物理序列号?
- 关闭窗口时错误
- pDC->Rectangle(m_rectPrint + CRect(0, 0, -20, 20))是什么意思?
- 谁给我讲讲keepalive吧
- WH_GETMESSAGE钩子拦截到消息后怎么得到接收此消息的窗口的句柄?
- 這個錯怎麼改 謝謝大家!!!warning C4305: '=' : truncation from 'const int ' to 'char '
- 网络编程高手请进来
- 关于CTreeCtrl消息的问题!
- VS2010 单文档 点击打开文件菜单后要使之前的菜单全部改变成另外一套菜单栏
- about client area and non-client area
- 我觉得好的项目管理才是开发商用软件的根本
查一查是否所有指针都正常
只有实现不了的东西,没有调试不出来的东西。
post原代码上来,让大家给你分析分析。
没有调试不好的问题。
95下应该是 MOV EAX,[EAX] ;EAX == 0 不过你何必要么用对话框这么软的东西,要么有像现在这样玩得这么硬呢?
用一下listing file和map档不是好多了吗?(希望提供) 我对这个问题有兴趣,今天要下线了?
想明白回答你。
2.确定自己的DLL已经是正确的版本;
3.比较你的本地的系统DLL和出错机器的相同名字的DLL的版本,例如MFC42.DLL,MSVCRT.DLL等;
完成上述步骤后,在运行程序,然后将结果在贴出来!
4.将用到的系统DLL与程序一起放到测试机器上发布运行!
Map文件的生成要做下面的设置:Project->Setting->Link中Generate mapfile
remote debug monitor, installing
调试:
remote debugging
你好!
你的原贴前加<>线程 ID 0x32c 的状态转储>eax=00452610 ebx=0012fa44 ecx=00000000 edx=004048de esi=0012f3f8 edi=00000001
>eip=004048e4 esp=0012f18c ebp=0012fa50 iopl=0 nv up ei pl nz ac po nc
>cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000216fs==3b,cs==1b可知运行于用户态
>函数: <nosymbols>**************************************************************************
这里推测(理由见后)应该有:
MOV ESI,ESP
以备以后堆栈寄存器检查MOV ECX,[EBP+8]
> 004048c6 8b09 mov ecx,[ecx] ds:00000000=????????
设置下面将调用的类函数的this指针参数
可知下面将调用的类函数使用__cdecl调用规则 > 004048c8 8b5508 mov edx,[ebp+0x8] s:00c7d026=????????
[ebp+0x8]是这个函数的第一个参数值,所以出错函数的第一个显式(explicit)参数是一个指向(指向类的指针)的指针。PPCFoo类型 > 004048cb 8b02 mov eax,[edx] ds:004048de=8be8458b
edx 是一个指向类的一个对象的指针的指针的值 PPCFoo类型 > 004048cd 8b10 mov edx,[eax] ds:00452610=5f7315a4
eax 是一个指向类的一个对象的指针值 pCFoo类型
edx 将是一个类的对象的第一个DWORD值,即pvtable值 > 004048cf ff5218 call dword ptr [edx+0x18]ds:00f51eb4=????????
在vtable中偏移0x18处取DWORD值作为函数地址调用,
以VC++的vtable布局,此处是调用第7个虚函数(以声明先后为序)。 > 004048d2 3bf4 cmp esi,esp
> 004048d4 e8cdaa0100 call 0041f3a6
调用__chechesp
检查堆栈清理是否正确,由于这是DEBUG版才有的,所以我相信这是个DEBUG版本的程序。
*************************************************************************
/////////////////////////////////////////////////////////////////////////*****框内部分(加上这个函数的部分原型推测)可反编译为:
SomeFunction(PPCfoo ppcfooArg...)
{
...
(*ppcfooArg)->vFun7(...);
...
}
或:(两种写法的目标码基本是一致的)
SomeFunction(PCFoo& rpcfooArg...) //注意是pass by reference
{
...
rpcfooArg->vFun7(...);
...
}///////////////////////////////////////////////////////////////////////////// > 004048d9 e9eb010000 jmp 00404ac9
这里看上去是一个
if()
{}
else
{}
的一部分。
> 004048de 8b45e8 mov eax,[ebp+0xe8] ss:00c7d026=????????
> 004048e1 8b480c mov ecx,[eax+0xc] ds:00f9fbe6=????????
>错误 ->004048e4 817904d00b0000 cmp dword ptr [ecx+0x4],0xbd0 >;ds:00b4d5d6=????????
> 004048eb 750c jnz 00410ff9
这里显示你使用了这么一套数据结构:
第一级数组(指针数组):每个元素是一个指向第二级数组的指针;
第二级数组(整数数组):每个元素很可能就是一个整数。第一级数组的基址(名称,指针)作为这个函数的某个参数传入。~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BTW ,这个函数的parameter区如此大,相信并不是你用了几十个参数,而是对class(或struct)用了pass by value,而非pass by address (或pass by reference,实际生成代码一样),用pass by value不但overhead大,还可能与你实际想做的不一样。suggestion:尽可能不要用pass by value。~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这里你想以第一级数组下标为3的元素(指针)为某第二级数组arrayX的基址,访问这个第二级数组arrayX下标为1的32位值。反编译为:
if(0xBD0 == *(*(ppnArg+3)+1))
{}
!!!!!!!!
!!!但可以看到你的第一级数组的元素(指针)并没有被正确赋值(出错时为0,即NULL)。
!!!导致了以0+4为地址访问第二级数组,出现非法的页故障。
!!!!!!!!
95下出错处CS:EIP处机器码应该是:
MOV EAX,[EAX]
CMP EAX,0BD0H
JNZ 04021A3H
MOV DWORD PTR [EBP-14],0H同样是
1.间接访问一个整数
2.与0BD0比较 // 这是定位错误的捷径。 (0BD0H = 3024)
时出错。!!!!!!!!!!!!!!!
!!!!!建议你查一下第一级数组(指针数组),保证它的元素被正确赋值。
!!!!!!!!!!!!!!!
>堆栈反向跟踪
>FramePtr ReturnAd Param#1 Param#2 Param#3 Param#4 Function Name>0012FA50 00415F8D 00451B7C 0045174C 00000000 0012FEDC !<nosymbols>
出错函数(你写的)>0012FAF0 5F444DEA 0012FEDC 0012FC90 7FFDF000 5F4B5B18 !<nosymbols>
直接调用出错函数的函数(你写的)>0012FB40 5F45A834 00000000 00000001 0012FEDC 0012FC90 !Ordinal4129
>0012FBDC 5F46178A 0043CCE8 0012FC20 5F4373FC 0012FEDC !Ordinal3773
>0012FBE8 5F4373FC 0012FEDC 0012FC90 7FFDF000 0000000A !Ordinal3774
>0012FC20 5F437B2B 0043CCE8 0000E100 00000000 0041EF20 !Ordinal563
>0012FC78 004148C3 0000E100 00000000 00000000 00000000 !Ordinal3657
从地址上看,推测都应该是MFC42D.DLL>0012FEE8 5F433523 00000000 000DEFF0 7FFDF000 0043CCE8 !<nosymbols>
不确定,极大的可能性是CwinApp::Run() (注意是虚函数)>0012FF08 0041FB38 00400000 00000000 00133009 00000001 !Ordinal1190
推测是AfxWinMain。>0012FF20 0041F663 00400000 00000000 00133009 00000001 !<nosymbols>
WinMain ,是MFC为你写的代码。>0012FFC0 77E67903 00000000 000DEFF0 7FFDF000 C0000005 !<nosymbols>
winmainCrtStartup Win32平台上C语言的startupcode ,它调用WinMain。
>0012FFF0 00000000 0041F4B0 00000000 000000C8 00000100 kernel32!>SetUnhandledExceptionFilter
系统的代码,设置SEH , 转入你的EXE文件…故障定位:
1。你的有个被MFC调用的函数A。A极可能是个消息处理函数,从堆栈反向跟踪看,消息被route的深度不深。
2。A又调用了函数B
3。B函数使用未正确赋值的指针数组的元素去访问内存,导致出错 //参见代码分析考虑你只在自己的机器上成功,研究一下是否Myprg使用了某个你这台机器才有的数据文件......!!请随时告诉大家调试结果!!
!!如果问题解决,告诉我们,但请不要马上给分;
!!这是个有趣的问题,请鼓励继续讨论,能从朋友们这里学到东西比得分更让我高兴。
请继续讨论!!!!
回oldworm,你可能没有看懂我的问题,在本机中程序是可以正确执行的,但是在别的机器上启动时出错,无法在IDE环境内调试,否则问题好办多了。
回holly,这一步我已经做了,不行,正如ultraunasm所说,问题很可能不在DLL,而是程序设计上的错误
至于好几位朋友说用远程调试,其实这也不行,因为远程调试必须两台机器都要装VC,但是一装VC就不会出错了。
回ultraunasm,我猜你绝对是高手,你的猜想都不幸言中。其实从感觉上我也认为是某个变量没有初始化,只是无法定位错误位置,不象你分析得如此透彻。
我会继续调试,因为在家无法调试,所以只有下星期回到单位再说,结果出来后再考诉大家。
如果涉及数据库, 检查一下 ado 的版本 2.0 or 2.1