2014-11-20 65 views
3

当控件离开'}'时,下面的代码崩溃。如果我用一个变量替换FieldByName() - > AsString,或者如果我删除了其他的,如果没有执行,它不会崩溃。当AV开始出现时,'=='被SameText取代。分析崩溃的diassembled C++代码

bool __fastcall TJwsSalesMethods::IsPORequiredForOrderAndCustomer(const String& OrderID, const String& CustomerID) 
{ 
    bool PORequired = false; 

    if (IsOrderCustomerPositioned(FqryWork01, CustomerID, OrderID)) // This function executes an SQL statement using FqryWork01->Open() 
    { 
    //String RequirePO = FqryWork01->FieldByName("RequirePO")->AsString; // Using variable instead will solve 
    if (SameText(FqryWork01->FieldByName("RequirePO")->AsString, "Y")) 
    { 
     PORequired = true; // This block is executed 
    } 
    else if (SameText(FqryWork01->FieldByName("RequirePO")->AsString, "N")) 
    { 
     PORequired = false; 
    } 
    else 
    { 
     PORequired = IsPORequiredForCustomer(CustomerID); 
    } 
    } //AV occurs here 

    return PORequired; 
} 

综观拆卸,

0053a40c  public JwsSalesUtil.cpp.TJwsSalesMethods.IsPORequiredForOrderAndCustomer: ; function entry point 
0053a40c 11784 push ebp 
0053a40d   mov  ebp, esp 
0053a40f   add  esp, -$54 
0053a412   mov  [ebp-$48], ecx 
0053a415   mov  [ebp-$44], edx 
0053a418   mov  [ebp-$40], eax 
0053a41b   mov  eax, $7cf0e0 
0053a420   call +$18c497 ($6c68bc)  ; __InitExceptBlockLDTC 
0053a425 11786 mov  byte ptr [ebp-$49], 0 
0053a429 11791 push dword ptr [ebp-$44] 
0053a42c   mov  ecx, [ebp-$48] 
0053a42f   xor  edx, edx 
0053a431   mov  eax, [ebp-$40] 
0053a434   call -$1ec9d ($51b79c)  ; JwsSalesUtil.cpp.TJwsSalesMethods.IsOrderCustomerPositioned 
0053a439   test al, al 
0053a43b   jz  loc_53a586 
0053a441 11794 mov  word ptr [ebp-$2c], $c 
0053a447   mov  edx, $7c1544   ; 'RequirePO' 
0053a44c   lea  eax, [ebp-4] 
0053a44f   call +$18ef14 ($6c9368)  ; System.UnicodeString.Create 
0053a454   inc  dword ptr [ebp-$20] 
0053a457   mov  edx, [eax] 
0053a459   mov  ecx, [ebp-$40] 
0053a45c   mov  eax, [ecx+$80] 
0053a462   call +$20285d ($73ccc4)  ; Data.Db.TDataSet.FieldByName (dbrtl180.bpl) 
0053a467   mov  [ebp-$50], eax 
0053a46a   lea  eax, [ebp-8] 
0053a46d   call -$135786 ($404cec)  ; ustring.h.System.UnicodeString.Create 
0053a472   mov  edx, eax 
0053a474   inc  dword ptr [ebp-$20] 
0053a477   mov  eax, [ebp-$50] 
0053a47a   mov  ecx, [eax] 
0053a47c   call dword ptr [ecx+$84] 
0053a482   lea  edx, [ebp-8] 
0053a485   push dword ptr [edx] 
0053a487   mov  edx, $7c154e 
0053a48c   lea  eax, [ebp-$c] 
0053a48f   call +$18eed4 ($6c9368)  ; System.UnicodeString.Create 
0053a494   inc  dword ptr [ebp-$20] 
0053a497   mov  edx, [eax] 
0053a499   pop  eax 
0053a49a   call +$20109d ($73b53c)  ; System.Sysutils.SameText (rtl180.bpl) 
0053a49f   push eax 
0053a4a0   dec  dword ptr [ebp-$20] 
0053a4a3   lea  eax, [ebp-$c] 
0053a4a6   mov  edx, 2 
0053a4ab   call +$18f120 ($6c95d0)  ; System.UnicodeString.Destroy 
0053a4b0   dec  dword ptr [ebp-$20] 
0053a4b3   lea  eax, [ebp-4] 
0053a4b6   mov  edx, 2 
0053a4bb   call +$18f110 ($6c95d0)  ; System.UnicodeString.Destroy 
0053a4c0   pop  ecx 
0053a4c1   test cl, cl 
0053a4c3   jz  loc_53a4ce 
0053a4c5 11796 mov  byte ptr [ebp-$49], 1 
0053a4c9 11797 jmp  loc_53a566 

剪断否则,如果与其他和从位置53a566

0053a566 11806 dec  dword ptr [ebp-$20] 
0053a569   lea  eax, [ebp-$14] 
0053a56c   mov  edx, 2 
0053a571  > call +$18f05a ($6c95d0)  ; System.UnicodeString.Destroy 
0053a576   dec  dword ptr [ebp-$20] 
0053a579   lea  eax, [ebp-8] 
0053a57c   mov  edx, 2 
0053a581   call +$18f04a ($6c95d0)  ; System.UnicodeString.Destroy 
0053a586 11812 mov  al, [ebp-$49] 
0053a589   mov  edx, [ebp-$3c] 
0053a58c   mov  fs:[0], edx 
0053a593 11813 mov  esp, ebp 
0053a595   pop  ebp 
0053a596   ret 

的AV继续发生,其中示出 '>'。我的问题是,为什么在第一块中有3个创建并且只有2个破坏,而在底部还有额外2个?所以如果我总共执行的代码有3个创建和4个破坏。我似乎也不知道哪个字符串对应于哪个Create和Destroy。我可以计算出“RequirePO”,AsString和“Y”构成了三个Create,也是创建不同地址的创建点之一。也许我没有正确阅读。

帮助赞赏。

问候, 马修喜悦

+0

什么是'String','AsString'和'SameText'? – Barry 2014-11-20 18:26:25

+1

我非常怀疑调试这需要转储汇编代码。只看代码,你使用的是指针,并假设它们都不是NULL。 – PaulMcKenzie 2014-11-20 18:58:49

+0

@PaulMcKenzie展望大会是最后的手段。没有新的或免费的。所有都在堆栈上创建。我的怀疑是不对的。这个特定的代码已经过多年的测试。现在将重新分解从==到SameText导致AV。我还删除了其中一项检查以简化拆卸过程。 – 2014-11-20 19:21:58

回答

2

貌似编译器给我一个代码生成错误。 0x0053a566的代码位为System.UnicodeString.Destroy,地址为[ebp-$14]作为参数。但是,[ebp-$14]似乎没有在任何地方初始化。

我敢打赌,[ebp-$14]将通过调用在你消隐代码拉伸被初始化为System.UnicodeString.Create(对应于else ifelse条款),这是周围跳了下去。

+0

查看asm后,一个明智的答案/评论。有一个错误,我可以用SameText和FieldName-> AsString的组合重现asm异常。大多数情况下它不会崩溃,但是存在错误异常。我会更进一步。谢谢。 – 2014-11-21 13:51:24

+0

Micheal,这就是答案。 ini在我剪切的部分中,所以它删除了没有创建的东西。有趣的是,第二个init(在else中)在第一个之前被销毁。如果我用'=='替换,那么在if asm中我会看到三个Create和三个我认为是正确的方式。谢谢你帮助我。我只知道一些基本的东西。我会用Embarcadero记录一个支持案例。 – 2014-11-21 16:17:02

+0

@MathewJoy你能找到'[ebp- $ 14]'字符串应该被创建的代码吗?这将阐明为什么会出现这个问题。 (这也为我敲响了一些钟声,过去提交了一些错误,在这些错误中AnsiStrings没有被正确创建或删除,与Property的使用相结合) – 2014-11-25 00:23:46