ertank 27 Posted September 27, 2020 Hello, First of all, I am not experienced about technical details of variable initialization and such. I am using Delphi 10.3.3 and targeting Win32 executable. I am running multiple threads in my application. One of the threads is making rest web service calls. Other does SOAP web service calls. Below unit is only used by rest web service thread and that thread only. Rest web service requires me to do logins for every 60 minutes. Problem appears at the second hour. Login requests sent as empty strings. I am sharing only relevant lines (timeout calculations, logging etc are not included below for simplicity): unit MyRestUnit; function Login(const AppKey, SecretKey: string): Boolean; implementation function Login(const AppKey, SecretKey: string): Boolean; var Request: string; Response: string; begin if AppKey.IsEmpty then Exit(False); if SecretKey.IsEmpty then Exit(False); Request := '{"appKey":"' + AppKey + '","secretKey":"' + SecretKey + '"}'; if uUtils.Http.PostIndy(URL, Request, Response) then // Rest of the function code is irrelevant end; Code is just as in above. Request is filled in and HTTP request is made. However, Request variable is filled in for the first time function is used. It is always becoming empty for the remaining calls. My log files says application is actually sending empty request bodies. Rest web service response error also confirms that. No garbage characters just empty. If I use debug run (F9) and check variable value at run time. It holds proper value for first call, second and following calls it is always empty. Same problem exists for Release build and Debug build. Only way I could make it always work is changing above code to something like below Request := EmptyStr; Request := '{"appKey":"' + AppKey + '","secretKey":"' + SecretKey + '"}'; I tried to use different local variable names (more than one) to rule out possible name collision and it still does not work for second calls to function, unless I first make it EmptyStr. It is also interesting that I do not get any compile time hint/warning like "value assigned is not used" or similar for my second example above. I have all hints and warnings turned on in my project. My internet searches did not result in something meaningful to me. My question is: Why first example does not work for the second and following calls? Asking in here because I could not find an explanation at all and I am really curious as to why. Moreover, that is the first time I am facing such a problem. Thanks & Regards, Ertan Share this post Link to post
FPiette 382 Posted September 28, 2020 var Request: string; begin Request := '{"appKey":"' + AppKey + '","secretKey":"' + SecretKey + '"}'; Request is a local variable and the way you initialize it is perfectly correct. Each time Login() is called, you get a new variable (on the stack) which is initialized. If this doesn't work, then there is something elsewhere corrupting memory. That will be difficult to find. Especially for us which have no view on your code. 1 Share this post Link to post
Kryvich 165 Posted September 28, 2020 Try remove const in the header of function Login. Share this post Link to post
ertank 27 Posted September 28, 2020 5 hours ago, FPiette said: Request is a local variable and the way you initialize it is perfectly correct. Each time Login() is called, you get a new variable (on the stack) which is initialized. If this doesn't work, then there is something elsewhere corrupting memory. That will be difficult to find. Especially for us which have no view on your code. I do have FastMM4 full debug open and it does not report a leak. I do not know if it also reports for corruptions though. Are there any hints/suggestions to search for such corruptions? Share this post Link to post
ertank 27 Posted September 28, 2020 25 minutes ago, Kryvich said: Try remove const in the header of function Login. That did not help. Share this post Link to post
FPiette 382 Posted September 28, 2020 26 minutes ago, ertank said: I do have FastMM4 full debug open and it does not report a leak. I do not know if it also reports for corruptions though. Are there any hints/suggestions to search for such corruptions? I use madExcept for that purpose. Be sure to select "crash instantly on buffer overflow" (or underflow). Share this post Link to post
ertank 27 Posted September 28, 2020 I just installed and tried madExcept. It doesn't report any buffer overflow or underflow (tried both). Though, there are some leaks reported like Mutex Handle, TCriticalSection, TIdThreadSafe. First one is my code in DPR file, last two being in the initialization sections of relevant units. It was interesting to have leak report even FastMM4 is not reporting any. Unfortunately, I failed to find a corruption using madExcept. I think is is harder to identify than I think it is. Thanks. Share this post Link to post
David Heffernan 2345 Posted September 28, 2020 Make a minimal reproduction. FastMM reports leaks only in the delphi heap. madExcept reports those leaks and also leaks in many other system resources. Share this post Link to post
Jacek Laskowski 57 Posted September 28, 2020 I guess inside the uUtils.Http.PostIndy() method, the Request parameter is somehow casted and associated with a buffer/indicator, which is later cleaned up by another part of the code (maybe thread?) Share this post Link to post
ertank 27 Posted September 28, 2020 While trying to prepare minimal reproduction I realize that there is an "else" exists above some explanatory remark lines and my Request variable assignment comes next. Turned out my mistake of leaving an else that should have been deleted at the first place. if TokenExpireTime <> 0 then begin // some other stuff with begin..end blocks end else // problem source line // some remark // another remark // more remark Request := '{"appKey":"' + AppKey + '","secretKey":"' + SecretKey + '"}'; It turned out that Request is conditionally filled in if no line above. Sorry about all the fuss and thanks to all. Share this post Link to post
FPiette 382 Posted September 28, 2020 5 minutes ago, ertank said: It turned out that Request is conditionally filled in if no line above. For that kind of bug, a step by step execution using the debugger make it obvious! Share this post Link to post
David Heffernan 2345 Posted September 28, 2020 As usual the most simple explanation was the answer. If a string variable is empty then the obvious explanation is that you either assigned it to be empty, or didn't assign it at all. Share this post Link to post
Anders Melander 1782 Posted September 28, 2020 Yet again the duck proves that it's invaluable. 2 Share this post Link to post
Rollo62 536 Posted September 28, 2020 (edited) 1 hour ago, ertank said: Turned out my mistake of leaving an else that should have been deleted at the first place. To avoid such hard-to-find mistakes, I use proper begin-end scopes ALWAYS ...... ( and I really, really mean ALWAYS, all the time ). That needs a lot of discipline over the years, that I dont always have. <cross-fingers> Since I did it that way, I never saw such failures again. </cross-fingers> Edited September 28, 2020 by Rollo62 1 Share this post Link to post
dummzeuch 1505 Posted September 28, 2020 Using a code formatter might also have highlighted this mistake. Just saying... Share this post Link to post