jonnyfive
asked on
Debugging a Service in D5
Hi everyone...
I want to attach my programm to the running service process, but despite following the instructions in the D5 help, I still get an Access Denied. I can't use the "Start Program first and then the Service" method, since the error occurs, when the Service stops. By the way, I use NT4 Server, Service Pack 6a.
Jonny...
I want to attach my programm to the running service process, but despite following the instructions in the D5 help, I still get an Access Denied. I can't use the "Start Program first and then the Service" method, since the error occurs, when the Service stops. By the way, I use NT4 Server, Service Pack 6a.
Jonny...
Obviously, you then have to scatter :
Debug( 'Got here' ) ;
And
DebugBuffer( ptr, ptrLen ) ;
sporadically throughout your code (I can also recommend putting them inside ifdefs:
{$IFDEF DEBUG}Debug( 'Got here' ) ;{$ENDIF}
And then you can compile them in by setting up a conditional define DEBUG (in Project/Options), and then remove them all by removing the define... Saved me hours...
Good luck again,
Tim.
Debug( 'Got here' ) ;
And
DebugBuffer( ptr, ptrLen ) ;
sporadically throughout your code (I can also recommend putting them inside ifdefs:
{$IFDEF DEBUG}Debug( 'Got here' ) ;{$ENDIF}
And then you can compile them in by setting up a conditional define DEBUG (in Project/Options), and then remove them all by removing the define... Saved me hours...
Good luck again,
Tim.
I found this somewhere on dejanews:
-------------------------- ----------
You can supply a parameter to set the run mode (-d for debugging, for instance, which runs the service in a normal context, that is, as a standard program and not a service).
-------------------------- ----------
--------------------------
You can supply a parameter to set the run mode (-d for debugging, for instance, which runs the service in a normal context, that is, as a standard program and not a service).
--------------------------
ASKER
All these are ideas, but not quite what I want to do. Even if I run the service as a normal program, I'm not able to "STOP" it. I just can shut it down, which doesn't help, since my bug occures exactly then. To do this, I don't need to implement any switches, I simply start the program from within Delphi and then the Service imidiatly afterwards and I can debug the startup & running, but not the shutdown. The reason for this is, when Delphi takes over, the Service manager thinks, that the Service is no longer running (but it is) and can not shut it down.
Any other ideas?
Regards, Jonny...
Any other ideas?
Regards, Jonny...
Hi jonny,
Really your user account has the rigth "Act like part of operational system" and "Debbug program" rigths ?
Well, I dont pass by this experience, but you can get a trial version of SoftIce do debug your service and if you get the symbols from M$ the Win32 API too.
Good luck, Radler.
Really your user account has the rigth "Act like part of operational system" and "Debbug program" rigths ?
Well, I dont pass by this experience, but you can get a trial version of SoftIce do debug your service and if you get the symbols from M$ the Win32 API too.
Good luck, Radler.
ASKER
In the meantime I fixed my problem (it was actually a timing problem (Main App finished, before a child thread was finished). Anyway... I still would like to know how to attach to a Service. Yes, I gave myself all available rights in the Usermanager (yes, also "Act like part of operating system"). Any other ideas? Does anyone got this to work?
Jonny...
Jonny...
You will have to add some security breaking code to your service. It includes the following steps: build a valid security descriptor with DACL set to nil, then call SetKernelObjectSecurity and pass the handle of the current process to it, followed by DACL_SECURITY_INFORMATION and security descriptor itself. Place this code before Application.Initialize for example. Now the DACL is set to nil which means that everyone has all possible rights on the service process and, of course, you can attach to it and debug it.
ASKER
Hi Aldyn...
I didn't had a chance to try this out yet. Do you have any "example" code ready by any chance :-]
Thanks, Jonny...
I didn't had a chance to try this out yet. Do you have any "example" code ready by any chance :-]
Thanks, Jonny...
Use something like this:
procedure BreakProcessSecurity; // (;-P)
var SD: PSECURITY_DESCRIPTOR;
begin
GetMem(SD,SECURITY_DESCRIP TOR_MIN_LE NGTH);
if not InitializeSecurityDescript or(SD,SECU RITY_DESCR IPTOR_REVI SION) then RaiseLastWin32Error;
if not SetKernelObjectSecurity(Ge tCurrentPr ocess,DACL _SECURITY_ INFORMATIO N,SD) then RaiseLastWin32Error;
FreeMem(SD);
end;
begin
BreakProcessSecutiry;
Application.Initialize;
............
procedure BreakProcessSecurity; // (;-P)
var SD: PSECURITY_DESCRIPTOR;
begin
GetMem(SD,SECURITY_DESCRIP
if not InitializeSecurityDescript
if not SetKernelObjectSecurity(Ge
FreeMem(SD);
end;
begin
BreakProcessSecutiry;
Application.Initialize;
............
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi Aldyn...
sorry for letting you wait this long, I just hadn't the time to test it. But I did now and it really works... I'm impressed :-) Well done...
Regards, Jonny...
sorry for letting you wait this long, I just hadn't the time to test it. But I did now and it really works... I'm impressed :-) Well done...
Regards, Jonny...
These are the functions I used, I hope they help (even though they do not answer your question)...
PROCEDURE Debug ( s : string ) ;
VAR
f : text ;
BEGIN
Assign ( f , 'C:\log.log' ) ;
{$i-} Append ( f ) ; IF ioResult <> 0 THEN Rewrite ( f ) ; {$i+}
WriteLn ( f , s ) ;
Close ( f ) ;
END ;
PROCEDURE DebugBuffer ( buffer : pointer ; len : longint ) ;
VAR
p : pchar ;
x , c : integer ;
s1 , s2 : string ;
BEGIN
p := buffer ;
x := 0 ;
FOR c := 1 TO len DO
BEGIN
IF x = 0 THEN
BEGIN
s1 := '' ;
s2 := '' ;
END ;
s1 := s1 + Copy ( '0123456789ABCDEF' , ( Ord ( p ^ ) DIV 16 ) + 1 , 1 ) +
Copy ( '0123456789ABCDEF' , ( Ord ( p ^ ) AND 15 ) + 1 , 1 ) +
' ' ;
IF Ord ( p ^ ) < 32 THEN
s2 := s2 + #0
ELSE
s2 := s2 + p ^ ;
Inc ( x ) ;
IF ( x = 16 ) THEN
BEGIN
Debug ( s1 + ' ' + s2 ) ;
x := 0 ;
END ;
Inc ( p ) ;
END ;
IF ( x > 0 ) THEN
BEGIN
FOR c := x TO 15 DO
BEGIN
s1 := s1 + ' ' ;
s2 := s2 + ' ' ;
END ;
Debug ( s1 + ' ' + s2 ) ;
END ;
END ;
Good luck with other (more suitable) answers =O)
Tim.