mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 10:39:39 +02:00
* Merging revisions r46369 from trunk:
------------------------------------------------------------------------ r46369 | michael | 2020-08-12 12:58:24 +0200 (Wed, 12 Aug 2020) | 1 line * Fix bug #37546, improvement to pass log filename to server ------------------------------------------------------------------------ git-svn-id: branches/fixes_3_2@46617 -
This commit is contained in:
parent
3d2c13d1f4
commit
d2160faebb
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -2918,7 +2918,6 @@ packages/fcl-base/examples/contit.pp svneol=native#text/plain
|
|||||||
packages/fcl-base/examples/crittest.pp svneol=native#text/plain
|
packages/fcl-base/examples/crittest.pp svneol=native#text/plain
|
||||||
packages/fcl-base/examples/csvbom.pp svneol=native#text/plain
|
packages/fcl-base/examples/csvbom.pp svneol=native#text/plain
|
||||||
packages/fcl-base/examples/databom.txt svneol=native#text/plain
|
packages/fcl-base/examples/databom.txt svneol=native#text/plain
|
||||||
packages/fcl-base/examples/dbugsrv.pp svneol=native#text/plain
|
|
||||||
packages/fcl-base/examples/debugtest.pp svneol=native#text/plain
|
packages/fcl-base/examples/debugtest.pp svneol=native#text/plain
|
||||||
packages/fcl-base/examples/decodeascii85.pp svneol=native#text/plain
|
packages/fcl-base/examples/decodeascii85.pp svneol=native#text/plain
|
||||||
packages/fcl-base/examples/demoio.pp svneol=native#text/plain
|
packages/fcl-base/examples/demoio.pp svneol=native#text/plain
|
||||||
@ -3684,6 +3683,7 @@ packages/fcl-process/Makefile.fpc svneol=native#text/plain
|
|||||||
packages/fcl-process/Makefile.fpc.fpcmake svneol=native#text/plain
|
packages/fcl-process/Makefile.fpc.fpcmake svneol=native#text/plain
|
||||||
packages/fcl-process/examples/checkipcserver.lpi svneol=native#text/plain
|
packages/fcl-process/examples/checkipcserver.lpi svneol=native#text/plain
|
||||||
packages/fcl-process/examples/checkipcserver.lpr svneol=native#text/plain
|
packages/fcl-process/examples/checkipcserver.lpr svneol=native#text/plain
|
||||||
|
packages/fcl-process/examples/dbugsrv.pp svneol=native#text/plain
|
||||||
packages/fcl-process/examples/demoproject.ico -text
|
packages/fcl-process/examples/demoproject.ico -text
|
||||||
packages/fcl-process/examples/demoproject.lpi svneol=native#text/plain
|
packages/fcl-process/examples/demoproject.lpi svneol=native#text/plain
|
||||||
packages/fcl-process/examples/demoproject.pp svneol=native#text/plain
|
packages/fcl-process/examples/demoproject.pp svneol=native#text/plain
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
program dbugsrv;
|
|
||||||
|
|
||||||
{$MODE OBJFPC}
|
|
||||||
{$H+}
|
|
||||||
{$APPTYPE CONSOLE}
|
|
||||||
|
|
||||||
uses
|
|
||||||
classes,SysUtils,simpleipc,dbugmsg;
|
|
||||||
|
|
||||||
Var
|
|
||||||
Srv : TSimpleIPCServer;
|
|
||||||
S : String;
|
|
||||||
Msg : TDebugMessage;
|
|
||||||
|
|
||||||
begin
|
|
||||||
Srv:=TSimpleIPCServer.Create(Nil);
|
|
||||||
Try
|
|
||||||
Srv.ServerID:=DebugServerID;
|
|
||||||
Srv.Global:=True;
|
|
||||||
Srv.Active:=True;
|
|
||||||
Srv.StartServer;
|
|
||||||
Writeln('Server started. Listening for debug messages');
|
|
||||||
Repeat
|
|
||||||
If Srv.PeekMessage(1,True) then
|
|
||||||
begin
|
|
||||||
Srv.MsgData.Seek(0,soFrombeginning);
|
|
||||||
ReadDebugMessageFromStream(Srv.MsgData,MSg);
|
|
||||||
Write(FormatDateTime('hh:nn:ss.zzz',Msg.MsgTimeStamp),': ');
|
|
||||||
Write(DebugMessageName(MSg.MsgType):12,' ');
|
|
||||||
Writeln(Msg.Msg);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
Sleep(10);
|
|
||||||
Until False;
|
|
||||||
Finally
|
|
||||||
Srv.Free;
|
|
||||||
end;
|
|
||||||
end.
|
|
||||||
|
|
142
packages/fcl-process/examples/dbugsrv.pp
Normal file
142
packages/fcl-process/examples/dbugsrv.pp
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
{
|
||||||
|
Make sure to set your project's options with, CompilerOptions --> Target "-o" -->Filename Value="fpcdebugserver",
|
||||||
|
i.e. the executable name must be the same as the client's const named dbugmsg.DebugServerID.
|
||||||
|
}
|
||||||
|
|
||||||
|
program dbugsrv;
|
||||||
|
|
||||||
|
{$MODE OBJFPC}
|
||||||
|
{$H+}
|
||||||
|
{$APPTYPE CONSOLE}
|
||||||
|
|
||||||
|
|
||||||
|
uses
|
||||||
|
classes,SysUtils,simpleipc,dbugmsg,strutils;
|
||||||
|
|
||||||
|
|
||||||
|
Type
|
||||||
|
|
||||||
|
{ THelperToWrite }
|
||||||
|
|
||||||
|
THelperToWrite = class
|
||||||
|
private
|
||||||
|
Class var StrLogFilename: string;
|
||||||
|
Class procedure WriteLnAllParams;
|
||||||
|
Class procedure InitParamsDependencies;
|
||||||
|
{ methods which override standard Write and WriteLn of the console output }
|
||||||
|
Class procedure DoWrite(const aBuffer: string);
|
||||||
|
Class procedure DoWrite(var aBuffer: string; const aMinimumFieldWidthIndent: integer); overload;
|
||||||
|
Class procedure DoWriteLn(const aBuffer: string);
|
||||||
|
{ methods which write in a log file, too }
|
||||||
|
Class procedure WriteNowThisLineInLog(aBuffer: string);
|
||||||
|
Class procedure WriteLnNowThisLineInLog(aBuffer: string);
|
||||||
|
Class function ReplaceSpecialCharsInLog(const aBuffer: string): string;
|
||||||
|
public
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
Var
|
||||||
|
Srv : TSimpleIPCServer;
|
||||||
|
Msg : TDebugMessage;
|
||||||
|
StrBuffer : string = '';
|
||||||
|
ObjFileStream : TFileStream = Nil;
|
||||||
|
|
||||||
|
|
||||||
|
class procedure THelperToWrite.WriteLnAllParams;
|
||||||
|
Var
|
||||||
|
iNumParam: integer;
|
||||||
|
sBuffer: string;
|
||||||
|
begin
|
||||||
|
sBuffer := 'ParamCount='+IntToStr(ParamCount)+LineEnding;
|
||||||
|
for iNumParam := 0 to ParamCount do
|
||||||
|
sBuffer := IfThen(iNumParam<>ParamCount, sBuffer+'ParamStr('+IntToStr(iNumParam)+') = "'+ParamStr(iNumParam)+'"'+LineEnding, sBuffer+'ParamStr('+IntToStr(iNumParam)+') = "'+ParamStr(iNumParam)+'"');
|
||||||
|
THelperToWrite.DoWriteLn(sBuffer);
|
||||||
|
end;
|
||||||
|
|
||||||
|
class procedure THelperToWrite.InitParamsDependencies;
|
||||||
|
begin
|
||||||
|
If (ParamCount<>0) then
|
||||||
|
if ParamStr(1)<>'' then begin {ord. params: 1st is a log filename}
|
||||||
|
THelperToWrite.StrLogFilename:= ParamStr(1);
|
||||||
|
ObjFileStream:= TFileStream.Create(THelperToWrite.StrLogFilename, fmCreate or fmOpenWrite or fmShareDenyWrite);
|
||||||
|
ObjFileStream.Position:= 0;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class procedure THelperToWrite.DoWrite(const aBuffer: string);
|
||||||
|
begin
|
||||||
|
Write(aBuffer);
|
||||||
|
if Assigned(ObjFileStream) then THelperToWrite.WriteNowThisLineInLog(StrBuffer);
|
||||||
|
end;
|
||||||
|
|
||||||
|
class procedure THelperToWrite.DoWrite(var aBuffer: string; const aMinimumFieldWidthIndent: integer);
|
||||||
|
begin
|
||||||
|
Write(aBuffer:aMinimumFieldWidthIndent,' ');
|
||||||
|
if Assigned(ObjFileStream) then THelperToWrite.WriteNowThisLineInLog(StrBuffer);
|
||||||
|
end;
|
||||||
|
|
||||||
|
class procedure THelperToWrite.DoWriteLn(const aBuffer: string);
|
||||||
|
begin
|
||||||
|
WriteLn(aBuffer);
|
||||||
|
if Assigned(ObjFileStream) then THelperToWrite.WriteLnNowThisLineInLog(aBuffer+LineEnding)
|
||||||
|
end;
|
||||||
|
|
||||||
|
class procedure THelperToWrite.WriteNowThisLineInLog(aBuffer: string);
|
||||||
|
var
|
||||||
|
sBuffer: string;
|
||||||
|
begin
|
||||||
|
sBuffer:= THelperToWrite.ReplaceSpecialCharsInLog(aBuffer);
|
||||||
|
ObjFileStream.Write(sBuffer[1],length(sBuffer));
|
||||||
|
end;
|
||||||
|
|
||||||
|
class procedure THelperToWrite.WriteLnNowThisLineInLog(aBuffer: string);
|
||||||
|
var
|
||||||
|
sBuffer: string;
|
||||||
|
begin
|
||||||
|
aBuffer:= ' '{sep. each field of the msg-record}+aBuffer+LineEnding;
|
||||||
|
sBuffer:= THelperToWrite.ReplaceSpecialCharsInLog(aBuffer);
|
||||||
|
ObjFileStream.Write(sBuffer[1],length(sBuffer));
|
||||||
|
end;
|
||||||
|
|
||||||
|
class function THelperToWrite.ReplaceSpecialCharsInLog(const aBuffer: string): string;
|
||||||
|
begin
|
||||||
|
Result := StringsReplace(aBuffer, [LineEnding+LineEnding], [LineEnding], [rfReplaceAll]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
ResourceString
|
||||||
|
SWelcomeOnSrv = 'IPC server started. Listening for debug messages:';
|
||||||
|
|
||||||
|
|
||||||
|
begin
|
||||||
|
Srv:=TSimpleIPCServer.Create(Nil);
|
||||||
|
Try
|
||||||
|
Srv.ServerID:=DebugServerID;
|
||||||
|
Srv.Global:=True;
|
||||||
|
Srv.Active:=True;
|
||||||
|
Srv.StartServer;
|
||||||
|
THelperToWrite.InitParamsDependencies;
|
||||||
|
THelperToWrite.WriteLnAllParams;
|
||||||
|
StrBuffer:=SWelcomeOnSrv;
|
||||||
|
THelperToWrite.DoWriteLn(StrBuffer);
|
||||||
|
Repeat
|
||||||
|
If Srv.PeekMessage(1,True) then
|
||||||
|
begin
|
||||||
|
Srv.MsgData.Seek(0,soFrombeginning);
|
||||||
|
ReadDebugMessageFromStream(Srv.MsgData,MSg);
|
||||||
|
StrBuffer:=FormatDateTime('hh:nn:ss.zzz',Msg.MsgTimeStamp)+': ';
|
||||||
|
THelperToWrite.DoWrite(StrBuffer);
|
||||||
|
StrBuffer:=DebugMessageName(MSg.MsgType);
|
||||||
|
THelperToWrite.DoWrite(StrBuffer,12);
|
||||||
|
StrBuffer:=Msg.Msg;
|
||||||
|
THelperToWrite.DoWriteLn(StrBuffer);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Sleep(10);
|
||||||
|
Until False;
|
||||||
|
Finally
|
||||||
|
if Assigned(ObjFileStream) then
|
||||||
|
ObjFileStream.Free;
|
||||||
|
Srv.Free;
|
||||||
|
end;
|
||||||
|
end.
|
||||||
|
|
@ -19,8 +19,11 @@ unit dbugintf;
|
|||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
|
uses dbugmsg;
|
||||||
|
|
||||||
Type
|
Type
|
||||||
TDebugLevel = (dlInformation,dlWarning,dlError);
|
TDebugLevel = (dlInformation,dlWarning,dlError);
|
||||||
|
TErrorLevel = Array[TDebugLevel] of integer;
|
||||||
|
|
||||||
procedure SendBoolean(const Identifier: string; const Value: Boolean);
|
procedure SendBoolean(const Identifier: string; const Value: Boolean);
|
||||||
procedure SendDateTime(const Identifier: string; const Value: TDateTime);
|
procedure SendDateTime(const Identifier: string; const Value: TDateTime);
|
||||||
@ -39,34 +42,33 @@ function GetDebuggingEnabled : Boolean;
|
|||||||
|
|
||||||
{ low-level routines }
|
{ low-level routines }
|
||||||
|
|
||||||
Function StartDebugServer : integer;
|
Function StartDebugServer(const aLogFilename : String = '') : integer;
|
||||||
Function InitDebugClient : Boolean;
|
Function InitDebugClient : Boolean;
|
||||||
Function InitDebugClient(const ShowOrNotPID: Boolean) : Boolean; overload;
|
function InitDebugClient(const ShowPID: Boolean; const ServerLogFilename: String = ''): Boolean;
|
||||||
|
procedure FreeDebugClient;
|
||||||
|
|
||||||
Const
|
|
||||||
SendError : String = '';
|
|
||||||
DefaultDebugServer = 'debugserver';
|
|
||||||
|
|
||||||
ResourceString
|
ResourceString
|
||||||
SProcessID = 'Process %s (PID=%d)';
|
SProcessID = '%d Process %s (PID=%d)';
|
||||||
SEntering = '> Entering ';
|
SEntering = '> Entering ';
|
||||||
SExiting = '< Exiting ';
|
SExiting = '< Exiting ';
|
||||||
SSeparator = '>-=-=-=-=-=-=-=-=-=-=-=-=-=-=-<';
|
SSeparator = '>-=-=-=-=-=-=-=-=-=-=-=-=-=-=-<';
|
||||||
SServerStartFailed = 'Failed to start debugserver. (%s)';
|
SServerStartFailed = 'Failed to start debugserver. (%s)';
|
||||||
|
|
||||||
Var
|
Var
|
||||||
DebugServerExe : String = DefaultDebugServer;
|
DebugServerExe : String = ''; { We can override this global var. in our compiled IPC client, with DefaultDebugServer a.k.a. dbugmsg.DebugServerID, or something else }
|
||||||
|
DefaultDebugServer : String = DebugServerID ; { A "last ressort" simplier compiled IPC server's name, called in command line by your client a.k.a. the compiler's target file "-o" }
|
||||||
|
SendError : String = '';
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
Uses
|
Uses
|
||||||
SysUtils, classes,dbugmsg, process, simpleipc;
|
SysUtils, classes, process, simpleipc, strutils;
|
||||||
|
|
||||||
Const
|
Const
|
||||||
DmtInformation = lctInformation;
|
DmtInformation = lctInformation;
|
||||||
DmtWarning = lctWarning;
|
DmtWarning = lctWarning;
|
||||||
DmtError = lctError;
|
DmtError = lctError;
|
||||||
ErrorLevel : Array[TDebugLevel] of integer
|
ErrorLevel : TErrorLevel
|
||||||
= (dmtInformation,dmtWarning,dmtError);
|
= (dmtInformation,dmtWarning,dmtError);
|
||||||
IndentChars = 2;
|
IndentChars = 2;
|
||||||
|
|
||||||
@ -224,21 +226,23 @@ begin
|
|||||||
Result := not DebugDisabled;
|
Result := not DebugDisabled;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function StartDebugServer : Integer;
|
function StartDebugServer(Const aLogFileName : string = '') : Integer;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
Cmd : string;
|
Cmd : string;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Cmd:=DebugServerExe;
|
Cmd := DebugServerExe;
|
||||||
if Cmd='' then
|
if Cmd='' then
|
||||||
Cmd:=DefaultDebugServer;
|
Cmd := DefaultDebugServer;
|
||||||
With TProcess.Create(Nil) do
|
With TProcess.Create(Nil) do
|
||||||
begin
|
begin
|
||||||
Try
|
Try
|
||||||
CommandLine:=Cmd;
|
Executable := Cmd;
|
||||||
|
If aLogFileName<>'' Then
|
||||||
|
Parameters.Add(aLogFileName);
|
||||||
Execute;
|
Execute;
|
||||||
Result:=ProcessID;
|
Result := ProcessID;
|
||||||
Except On E: Exception do
|
Except On E: Exception do
|
||||||
begin
|
begin
|
||||||
SendError := Format(SServerStartFailed,[E.Message]);
|
SendError := Format(SServerStartFailed,[E.Message]);
|
||||||
@ -261,7 +265,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
Msg.MsgType:=lctStop;
|
Msg.MsgType:=lctStop;
|
||||||
Msg.MsgTimeStamp:=Now;
|
Msg.MsgTimeStamp:=Now;
|
||||||
Msg.Msg:=Format(SProcessID,[ApplicationName, GetProcessID]);
|
Msg.Msg:=Format(SProcessID,[GetProcessID, ApplicationName, GetProcessID]);
|
||||||
WriteMessage(Msg);
|
WriteMessage(Msg);
|
||||||
end;
|
end;
|
||||||
if assigned(MsgBuffer) then FreeAndNil(MsgBuffer);
|
if assigned(MsgBuffer) then FreeAndNil(MsgBuffer);
|
||||||
@ -272,17 +276,25 @@ end;
|
|||||||
|
|
||||||
Function InitDebugClient : Boolean;
|
Function InitDebugClient : Boolean;
|
||||||
|
|
||||||
|
begin
|
||||||
|
InitDebugClient(False,'');
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function InitDebugClient(const ShowPID: Boolean; const ServerLogFilename: String = ''): Boolean;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
msg : TDebugMessage;
|
msg : TDebugMessage;
|
||||||
I : Integer;
|
I : Integer;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
|
AlwaysDisplayPID:= ShowPID;
|
||||||
DebugClient:=TSimpleIPCClient.Create(Nil);
|
DebugClient:=TSimpleIPCClient.Create(Nil);
|
||||||
DebugClient.ServerID:=DebugServerID;
|
DebugClient.ServerID:=DebugServerID;
|
||||||
If not DebugClient.ServerRunning then
|
If not DebugClient.ServerRunning then
|
||||||
begin
|
begin
|
||||||
ServerID:=StartDebugServer;
|
ServerID:=StartDebugServer(ServerLogFileName);
|
||||||
if ServerID = 0 then
|
if ServerID = 0 then
|
||||||
begin
|
begin
|
||||||
DebugDisabled := True;
|
DebugDisabled := True;
|
||||||
@ -308,17 +320,11 @@ begin
|
|||||||
MsgBuffer:=TMemoryStream.Create;
|
MsgBuffer:=TMemoryStream.Create;
|
||||||
Msg.MsgType:=lctIdentify;
|
Msg.MsgType:=lctIdentify;
|
||||||
Msg.MsgTimeStamp:=Now;
|
Msg.MsgTimeStamp:=Now;
|
||||||
Msg.Msg:=Format(SProcessID,[ApplicationName, GetProcessID]);
|
Msg.Msg:=Format(SProcessID,[GetProcessID, ApplicationName, GetProcessID]);
|
||||||
WriteMessage(Msg);
|
WriteMessage(Msg);
|
||||||
Result := True;
|
Result := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function InitDebugClient(const ShowOrNotPID: Boolean): Boolean;
|
|
||||||
begin
|
|
||||||
AlwaysDisplayPID:= ShowOrNotPID;
|
|
||||||
Result:= InitDebugClient;
|
|
||||||
end;
|
|
||||||
|
|
||||||
Finalization
|
Finalization
|
||||||
FreeDebugClient;
|
FreeDebugClient;
|
||||||
end.
|
end.
|
||||||
|
@ -22,7 +22,7 @@ interface
|
|||||||
uses Classes;
|
uses Classes;
|
||||||
|
|
||||||
Const
|
Const
|
||||||
DebugServerID : String = 'fpcdebugserver';
|
DebugServerID = 'fpcdebugserver'; { compiled IPC server's IDentifiant-name. Should be the same as the compiled IPC client dbugintf.DefaultDebugServer }
|
||||||
|
|
||||||
lctStop = -1;
|
lctStop = -1;
|
||||||
lctInformation = 0;
|
lctInformation = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user