2014-11-20 107 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