Discussion:
[Lazarus] Is it possible to find the location of an EAccessViolation, with Lazarus?
Carlos E. R. via Lazarus
2018-05-12 13:07:30 UTC
Permalink
Hi,

a program of mine crashed with:

Exception at 0000000000401B4A: EAccessViolation:
Access violation.


Is it possible to find the location line of that address?


Very long ago, with turbopascal, it was possible to type the address of the fault in a box in the compiler, which would build again the source and stop at the exact location. I do not see similar thing in Lazarus. Did I miss it?



I know where it happened, more or less, from the messages on screen and syslog.
Maybe someone here can see the problem in the code.


procedure TMyApplication.DoRebootRouter;
{See <http://wiki.freepascal.or/Executing_External_Programs#TProcess>
for the doc on calling a program and getting its output.}
const
BUF_SIZE = 2048; // Buffer size for reading the output in chunks
var
AProcess : TProcess;
OutputStream : TStream;
BytesRead : longint;
Buffer : array[1..BUF_SIZE] of byte;
ExitCode,
ExitStatus : Integer;
begin
LastRouterRebootTimestamp:= Now;
inc(RebootTimes);
ExitCode := -1;
AProcess := TProcess.Create(nil);
try
AProcess.Executable := '/usr/local/bin/egctl';
AProcess.Parameters.Add('Regleta');
AProcess.Parameters.Add('off');
AProcess.Parameters.Add('off');
AProcess.Parameters.Add('off');
AProcess.Parameters.Add('off');

AProcess.Execute; <==== this does execute.
OutputStream := TMemoryStream.Create;
repeat
BytesRead := AProcess.Output.Read(Buffer, BUF_SIZE);
OutputStream.Write(Buffer, BytesRead)
until BytesRead = 0;
ExitCode:= AProcess.ExitStatus;
ExitStatus:= AProcess.ExitStatus
finally
AProcess.Free;
end;

syslog(log_info, 'Called %s, got EC: %d ED: %d'#10, ['egctl', ExitCode, ExitStatus]); <==== this part doesn't execute.
Writeln('Got exitcode ', AProcess.ExitCode, ' ExitStatus: ', AProcess.ExitStatus);



The external program runs fine.

The screen output was:

Last sucessfull ping was more than 60 seconds ago, rebooting the router.
Exception at 0000000000401B4A: EAccessViolation:
Access violation.
socket 1 - off <=== child program
socket 2 - off
socket 3 - off
socket 4 - off


Syslog entries are these:

<16.6> 2018-05-12T07:25:18.455969+02:00 Isengard WatchDog - - - WatchDog MARK! Status: Router 1 (F/T 0/48) Google 1 (F/T 0/8) Rebooting 0 Reboots 0
<16.6> 2018-05-12T07:47:20.514116+02:00 Isengard WatchDog - - - Last sucessfull ping was more than 60 seconds ago, rebooting the router.
<16.6> 2018-05-12T07:47:20.515184+02:00 Isengard WatchDog - - - Ending

The second line indicates that the procedure shown above is called.

The third line comes from here:


destructor TMyApplication.Destroy;
begin
ping.Free;
syslog(log_info,'Ending',[1234]);
closelog;
inherited Destroy;
end;



Ideas?
--
Cheers / Saludos,

Carlos E. R.
(from 42.3 x86_64 "Malachite" at Telcontar)
Carlos E. R. via Lazarus
2018-05-13 12:29:51 UTC
Permalink
Although the child is not using pipes :-?
If the child process outputs something (text or something else), then it
is using stdout pipe. And if you want access to this output, then you
need to set poUsePipes enum in the TProcess.Options so TProcess can set
up IO redirection correctly.
Ah. Then it is the parent who is setting an implicit pipe. That is an
important "detail" that I didn't notice/read about.
Also do not forget read TProcess.StdErr pipe, otherwise there is change
for strange behaviour. Or add poStderrToOutPut to TProcess.Options.
Well, of course I did not set it up, because I did not see it in the
example I was following or in the documentation. Thanks for telling me!

<http://wiki.freepascal.org/TProcess>
<http://wiki.freepascal.org/Executing_External_Programs#TProcess>
<https://www.freepascal.org/docs-html/fcl/process/tprocess.html>
--
Cheers / Saludos,

Carlos E. R.
(from 42.3 x86_64 "Malachite" at Telcontar)
Loading...