源代码一人一份,我们才能分析。byte 码谁能看懂.

解决方案 »

  1.   

    看起来好象指针(EDS:EAX)错
    查一查是否所有指针都正常
      

  2.   

    我调试程序好像很少看这些出错的东西,到现在为止没有发现调试不好的东西。
    只有实现不了的东西,没有调试不出来的东西。
    post原代码上来,让大家给你分析分析。
      

  3.   

    建议在debug模式运行,出错后使用菜单看Call Stack,再反向过去找调用函数,一下就发现问题了。
    没有调试不好的问题。
      

  4.   

      95和2000出错处不一样。
      95下应该是 MOV EAX,[EAX] ;EAX == 0  不过你何必要么用对话框这么软的东西,要么有像现在这样玩得这么硬呢?
      用一下listing file和map档不是好多了吗?(希望提供)  我对这个问题有兴趣,今天要下线了?
      想明白回答你。
      

  5.   

    1.用VC的Depends工具检查你的程序用到的系统的DLL和自己的DLL都有哪些;
    2.确定自己的DLL已经是正确的版本;
    3.比较你的本地的系统DLL和出错机器的相同名字的DLL的版本,例如MFC42.DLL,MSVCRT.DLL等;
    完成上述步骤后,在运行程序,然后将结果在贴出来!
      

  6.   

    补充:
    4.将用到的系统DLL与程序一起放到测试机器上发布运行!
      

  7.   

    在Debug状态下面生成Map文件,根据Map文件里面的地址信息可以大致定位到函数,然后在函数里面设置调试信息。
    Map文件的生成要做下面的设置:Project->Setting->Link中Generate mapfile
      

  8.   

    你可以试一试VC的远程调试,安装请参考MSDN索引中的
    remote debug monitor, installing
    调试:
    remote debugging
      

  9.   

    remote debugging是需要两台机器都有VC才行!
      

  10.   

    我想你在2000下仔细调试,一般来说,在NT下通过的程序在9x下也能通过,如果不行的话,在NT下会有错误的只不过没有暴露而已。你查查有没有内存之类的问题。
      

  11.   

    happymood:
    你好!
    你的原贴前加<>线程 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使用了某个你这台机器才有的数据文件......!!请随时告诉大家调试结果!!
    !!如果问题解决,告诉我们,但请不要马上给分;
    !!这是个有趣的问题,请鼓励继续讨论,能从朋友们这里学到东西比得分更让我高兴。
    请继续讨论!!!!
      

  12.   

    这两天上不了CSDN,所以现在才发这篇贴子。
    回oldworm,你可能没有看懂我的问题,在本机中程序是可以正确执行的,但是在别的机器上启动时出错,无法在IDE环境内调试,否则问题好办多了。
    回holly,这一步我已经做了,不行,正如ultraunasm所说,问题很可能不在DLL,而是程序设计上的错误
    至于好几位朋友说用远程调试,其实这也不行,因为远程调试必须两台机器都要装VC,但是一装VC就不会出错了。
    回ultraunasm,我猜你绝对是高手,你的猜想都不幸言中。其实从感觉上我也认为是某个变量没有初始化,只是无法定位错误位置,不象你分析得如此透彻。
    我会继续调试,因为在家无法调试,所以只有下星期回到单位再说,结果出来后再考诉大家。
      

  13.   

    如何已知的DLL都准备好的话,请使用Debug模式,然后使用TRACE进行跟踪,就是需要在你的程序中加入TraceWin或使用Lodprf32,具体原理可参见候俊杰的<<深入浅出MFC2>>,这是我目前所知道在没有VC上进行调试的方法。
      

  14.   

    检查以下数组是否过大, 指针是否初始化, 另外, 该程序是否可以运行在 NT 4.0 上.
    如果涉及数据库, 检查一下 ado 的版本 2.0 or 2.1
      

  15.   

    回各路高手,经过无数次的加消息框,无数次的编译,无数次的拷贝,俺终于精确定位到出错的代码,(*ppDatabase)->Open(fileName, TRUE, FALSE, "");但是奇怪的是居然catch不到错误,难怪这么难调试。我做出了一个演示程序,需要的朋友请举手!