alogrep 0 Posted December 12, 2022 Hello everybody. Another one of my misteries . I have created a component Tslim(TComponent); It is basically a table with cells and row that are created dynamically. In a particular procedure that creates new cells and rows, something happens that suddenly the Slim becomes NIL. That is in a try… except block, when the exception is raised, I inspect the value of Slm, and it shows NIL. The Slim.Destroy is not triggered. Is the a way or something (an Event?) that could be triggered the moment this happens so I can find out what exactly causes that? Share this post Link to post
alogrep 0 Posted December 12, 2022 I found where the problem occurs (see apptached image). However the call stack doesn't go inside the procedure where the problem actually happes. This is the code procedure (g:Tslim; html:string); var c,r: integer; begin C:=0; R:=0; WITH G DO // this is the "slim" component while (HTML <> '') and (html <> ';') and (copy(html,1,5)<>'slim:') DO BEGIN try N:=POS('<col',html); if n>0 then begin if c> colcount-1 then colcount:=c; if alreadytranslated then begin if (g=extras) and (c=0) and (r>0) and (copy(html,1,5) <> _nota) then cells[c,r]:=' '+copy(html,1,n-1) else cells[c,r]:=copy(html,1,n-1); end else if (g=extras) and (c=0) and (r>0) and (copy(html,1,5) <> _nota) then cells[c,r]:=' '+Fromspanish(copy(html,1,n-1)) else cells[c,r]:=FromSpanish(copy(html,1,n-1)); system.delete(html,1,n+3); if (g=extragrid) and (c=0) then begin k:=pos('line-through',html); if (k>0) then begin orderline.disabledrows[r]:=true; system.delete(html,k,12); end; end; n:=pos('color:::',html); if (n=1) then begin if (copy(html,9,4) <> 'null')then begin if copy(html,9,1) ='#' then begin cellcolors[c,r]:=HexcolToTcolor(copy(html,10,6)); system.delete(html,1,15); end else begin cellcolors[c,r]:=HexcolToTcolor(copy(html,9,6)); system.delete(html,1,14); end; end else system.delete(html,n,12); end; k:=pos('<row',html); if k=1 then begin system.delete(html,1,k+3); c:=-1; // inc() below to 0 inc(r); if r> rowcount-1 then rowcount:=rowcount+1; kount:=rowcount; end; inc(c); end else break; EXCEPT showmessage(inttostr(c)+' '+inttostr(r)+' '+sparam); END; end; end; Share this post Link to post
programmerdelphi2k 237 Posted December 12, 2022 (edited) my first tip: avoid "WITH" usage, always that possible! it's messy and leads to basic error induction, even though everything looks ok in the build! if "G" it's your component, then, maybe you should look before this line... what happens before this line? "With G do..." because, when "G" ...ColCount.../ Cells[...] / ...CellColors[...] etc... --> if "G" is nil, then you catch a "AV". Edited December 12, 2022 by programmerdelphi2k Share this post Link to post
Dave Nottage 557 Posted December 12, 2022 17 minutes ago, alogrep said: However the call stack doesn't go inside the procedure where the problem actually happes. Then the problem is not actually happening inside that procedure (though the root cause may be there). The problem is occurring in a method in the Http unit, in a class called TTCPHttpThrd in a method with a name starting with "ProcessH", but the rest of the callstack window is cut off in your screenshot Share this post Link to post
Dalija Prasnikar 1396 Posted December 12, 2022 4 hours ago, alogrep said: I found where the problem occurs (see apptached image). However the call stack doesn't go inside the procedure where the problem actually happes. This is the code There is a thread involved. Most likely not all data that needs to be protected is protected and another thread is either releasing the object while it is still in use, or there is memory corruption because multiple threads are messing with the data. But there is not enough code to pinpoint the problem. Share this post Link to post
alogrep 0 Posted December 13, 2022 What I don’t understand is: how come the G variable is set to NIL? From what I have seen if an object is destroyed for say AV, it is destroyed but not set to NIL. A to send more code, it is not feasible because is too long and nobody would take the time or have the patience to read it. I can give the “scheme” I use.. type tgrids=record g1,hgrid,tabgrid,extras,extragrid,groupqty,servgrid,all,mitad1,mitad2:Tslim; end; type OrderLinevars = record grids: Tgrids; myCompname_,pass, curtabtrans:string // and a bunch of other variables; end; type orderlinerec = record id: string; orderline: OrderLinevars; end; type orderlinearr= array of orderlinerec; PtRecord=^OrderLinevars; in main form I have this public orderlines : orderlinearr; TTCPHttpThrd = class(TThread) private Sock:TTCPBlockSocket; orderline: PTREcord; thisip,objs: string; ......... When there is a new POST request, a new thread is created and executed/ in the Execute part, as the first thing, I do FOR N:=0 TO HIGH(MAIN.ORDERLINES) do if (MAIN.orderlines[n].id=thisip) then begin orderline:=@MAIN.orderlines[n].orderline; orderlineindex:=n; break; end; if orderlineindex<0 then begin setlength(main.orderlines,length(main.orderlines)+1); orderlineindex:=high(main.orderlines); MAIN.orderlines[orderlineindex].id:=thisip; orderline:=@MAIN.orderlines[orderlineindex].orderline; end; The "orderline" is used (for brevity) in all calculations inside the execute. I need some variables that are part of the orderlinerec -> OrderLinevars to be persistent; All the grids are set to NIL at the beginning of Execute, freed at the end; For example, a POST requests set some variables that I need to re-use later for another POST request from the same user. Just as lost as before. Share this post Link to post
Dave Nottage 557 Posted December 13, 2022 1 hour ago, alogrep said: A to send more code, it is not feasible because is too long and nobody would take the time or have the patience to read it. You could at least post the code for whatever the method is that starts with "ProcessH", as per my earlier comment. You provided a screenshot and said that is where the problem occurs. Share this post Link to post
Dalija Prasnikar 1396 Posted December 13, 2022 What is main? You are most likely corrupting a memory by accessing same data from main thread and background thread. Also you shouldn't work with any visual control from the background thread without calling the TThread.Synchronize or TThread.Queue Also you are working with pointers, so it is possible that you are accidentally overwriting something. Share this post Link to post