The code below crashes when the control leaves '}'. If I replace FieldByName()->AsString with a variable or if I remove the else if that is not executed, it doesn't crash. '==' was replaced by SameText, when the AV started to occur.
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;
}
Looking at the disassembly,
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
snip else if and else and continuing from location 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
The AV occurs where '>' is shown. My question is, why is there 3 creates and only 2 destroys in the first block and in the bottom there are extra 2? So if I total the executed code there are 3 creates and 4 destroys. I also don't seem to know which string corresponds to which Create and Destroy. I can figure out "RequirePO", AsString and "Y" constitutes the three Create and also one of the create points to a different address. Maybe I am not reading it right.
Help appreciated.
Regards, Mathew Joy
Looks like a codegen bug in the compiler to me. The bit of code at 0x0053a566
is calling System.UnicodeString.Destroy
with the address of [ebp-$14]
as an argument. However, [ebp-$14]
doesn't seem to have been initialized anywhere.
I'll bet that [ebp-$14]
will be initialized by a call to System.UnicodeString.Create
in the stretch of code you elided (that corresponds to the else if
and else
clauses) which is jumped around.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.