That can be hard to fix :( My service is working "fine" for a few minutes so it raises and exception "Class aborted (6)" and the break point end at libc.so. So if I am not in the IDE I have to uninstall or restart the device because it becomes stucked on memory and I cannot kill it.

That can be hard to fix :( My service is working "fine" for a few minutes so it raises and exception "Class aborted (6)" and the break point end at libc.so. So if I am not in the IDE I have to uninstall or restart the device because it becomes stucked on memory and I cannot kill it.
I am commenting some special parts to try to get the error, so far no luck.
A critical part will envolve this:

lJsonStream := TStringStream.Create(Utf8Encode(AJson));
lIdHTTP := THTTPClient.Create;
lIdHTTP.CustomHeaders['auth'] := Auth;
lIdHTTP.CustomHeaders['uid'] := uID;
lIdHTTP.ContentType := 'application/json';
lUrl := FBaseURL + APIResource;
AResponseContent := TStringStream.Create();
lIdHTTP.Put(lUrl, lJsonStream, AResponseContent);
lJsonStream.DisposeOf;

That part will write data to Google Firebase, it works, but I suspect something here...

Comments

  1. I would suspect something going wrong when putting. Shouldn't the put be wrapped in a try except block?

    ReplyDelete
  2. Roland Kossow Yes, I will put a try/except. The original code was lack of the DisposeOf too, I thought could be some toons of leaked memory, but no.

    ReplyDelete
  3. Actually I take a second look and there are 2 other objects created without been free. Protected with try/finally

    ReplyDelete
  4. You might also want to check "if not IJsonStream.Disposed then"

    ReplyDelete
  5. Roland Kossow :( bad news.. After a lot of tries I simple commented the function call and let the app runs looping without posting anything. I crashed the same way. Maybe a fresh project could help? :( :(

    ReplyDelete
  6. Can you provide the current source and maybe the context of the put call. Sound like a race condition to me.

    ReplyDelete
  7. Sure:

    function TDM.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer;
    begin
    Result := TJService.JavaClass.START_STICKY;
    Processar();
    end;
    ----------------
    Into this function it will make the job, here I have the main loop
    //procedure Processar()...
    TTask.Run(
    procedure
    begin
    i := 1;
    // the Main Loop
    while True do
    begin

    if not LConfigurado then
    begin
    UpdateConfig();
    LConfigurado := true;
    end;

    if LConfigurado and ((FSendData) or (LForcePosition)) then
    begin
    //
    SendData(i, LForcePosition);
    end;

    LForcePosition := ((i mod FTempoTX) = 0); // and FForcePosition
    inc(i);

    Sleep(1000);
    // MotionSensor();

    end;
    end);
    --
    The procedure named "SendData" has a test for checking if the app is connected, if not it will keep data into the memory (stringlist) and check/recovery on the next iteration, getting it from the buffer:

    function TDM.RecuperaBuffer: String;
    var
    i: Integer;
    begin
    Result := '';
    i := FBuffer.Count - 1;
    if i = -1 then
    Exit;

    Result := FBuffer[i];
    FBuffer.Delete(i);
    end;

    ReplyDelete
  8. I think you need to prevent concurrency issues in your code, just accessing FSendData like that from a TTask might cause problems. Not?

    ReplyDelete
  9. Well, now I am a bit lost because it should be (it is) a simple code. Once the Task is running and was called I suppose it will not be recursive so I can't see concurrency issues here. I will try another approach but I am running out of options.
    Thank you!

    ReplyDelete
  10. Roland Kossow Well, maybe yes. I just fixed it, so far so good. Fixed by creating a fresh new project. Copied all the methods and working fine. No more crashes and I will let it run a whole day, before it the app would crash just after few minutes

    ReplyDelete

Post a Comment