I’ve been meaning to get around to writing this post for a wee while, but finally Vish’s post on AGS logging has prompted me to actually do it. I should begin by crediting a friend who put me onto this tip for debugging Server Object Extensions (SOE) because it has saved me a great deal of time!
So as Vish mentions debugging SOE’s can be a bit tricky and up until a few months ago I took a combined approach:
1. Write the core SOE functionality remotely first before porting it to a SOE to make sure that my logic was basically ok
2. Logging using the ILogSupport interface.
This approach is very time consuming especially the first step, so it was a relief to find that through attaching to the SOC process which was hosting the SOE from within a live debug session in Visual Studio allowed me to step into the SOE and debug it directly! Here’s a walk-through:
1. Firstly stop all the services you don’t want to debug within AGS – this can be done via AGS Manager or ArcCatalog.
2. Configure the service you wish to debug so that it only has a single instance running – this can be done by looking at the service properties and setting the minimum number of instances to one. By doing this it helps to isolate the correct process to attach to when debugging:

3. Ok now open your project/solution in Visual Studio – usually I include the SOE into a solution with the SOE client, so for example I have a console application that creates a connection a web service which in turn connects to AGS:
private ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection agsconn = new ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection(); private ESRI.ArcGIS.Server.IServerObjectManager serverManager; private ESRI.ArcGIS.Server.IServerContext sc = null; private ESRI.ArcGIS.Server.IServerObject so; private ESRI.ArcGIS.Server.IServerObjectExtensionManager soexm; private ESRI.ArcGIS.Server.IServerObjectExtension soext; private soe.LrsServerObjectExt localSoe;//create a connection to the gis server agsconn.Host = "pc302926"; agsconn.Connect(); //create a context serverManager = agsconn.ServerObjectManager; sc = serverManager.CreateServerContext(mapServer, "MapServer"); //get the soe so = sc.ServerObject; soexm = (ESRI.ArcGIS.Server.IServerObjectExtensionManager)so; soext = soexm.FindExtensionByTypeName(soeName); //create a local instance of the soe localSoe = (soe.LrsServerObjectExt)soext; return localSoe.getThroughDistanceIndex(asset.X, asset.Y, 10); |
4. In the code here the web service connects to AGS and a local instance of the SOE is created for use by the web service.
5. Create a breakpoint at a suitable point before the SOE is actually called – in the sample above perhaps the ‘localSoe = (soe.LrsServerObjectExt)soext;’ might be a good point.
6. Place another breakpoint at the entry point of the SOE itself (not shown above)
7. Run the code in debug mode ensuring that your client is set as the start up project and wait for the first breakpoint to be hit
8. Once it hits the breakpoint, in Visual Studio launch the Attach To Process window (debug>attach to process):

9. Ok now you can attach to the SOC instance which is hosting your SOE (the single instance you configured in step 2) – there will be a number of SOC instances available – the instance you want to attach to is the managed instance (if you didn’t choose to do step two and you have multiple SOC processes running then you may want to attach to them all.) I also find that process explorer is handy for isolating the correct service – AGS automatically utilises two SOC processes for managing itself therefore with a single service running with a single instance you should have three SOC processes running – two dedicated to the server itself and a third which is being used by the service. When using process explorer ensure that the lower pane is visible (view>show lower pane CTL>L) by selecting a process the lower pane will display properties – the SOC process which is dedicated to the service will appear with a lot more properties than those being used by AGS itself.

10. So now you can continue to step through the code and you should step into the SOE itself

This is helpful at development time, but obviously it doesn’t preclude the use of logging as per Vish’s post. Another step which can help when debugging SOE based applications (but not actually debugging the SOE itself) is to ensure that the Visual Studio does not attempt to build the SOE each time you begin debugging. You can configure this via the Configuration Manager within Visual Studio(Project>Configuration Manager). The reason that this is useful is that if you attempt to build the SOE each time you begin to debug you’ll find that the AGS SOC process holds a lock onto the SOE assembly and you will be unable to complete a build forcing you to stop the service before building which is a bit tedious if you are not actually debugging the SOE.
Michael / February 1st, 2010 21:47
thanks for this! it is definitely very helpful…
Michael / February 8th, 2010 22:11
Simon, I think I could use a bit of your help here…. in fact I was able to debug my custom SOE a few times, but after a new build it seems like I can’t debug any longer. the message that I get at the ‘attach to the process’ step is :
“the following modulre was build either with optimizations enabled or without debug information…”
any ideas on how to workaround this ?
fyi: I’m not using the strong key signature of my libraries yet….
thanks !
mapbutcher / February 8th, 2010 22:42
Michael. Just a stab at what might be happening.
The SOC process you attach to has an instance of your SOE running within it. This instance is governed by the registration of the SOE with COM (and optionally the GAC) and the registration of the SOE with AGS in the server extension types configuration file. When you build you typically re-register your debug configuration (which includes the debug assemblies) of your SOE and restart the SOM this will ensure that with each build the SOC processes are re-initialising the debug configuration of your SOE.
Basically it sounds like your SOCs are intialising a configuration of your SOE which does not have debug assemblies. Hope this helps?
Simon
Michael / February 8th, 2010 22:50
resolved. I have had some post-build events taking place and forgot to point the interface reference to new location. thanks
Giser / April 13th, 2010 21:02
Hey Simon, I am quite new to the SOE and trying to get the AGS sample (SimpleSOE_CSharp) to work on my local machine (with both web, SOM/SOC). Do you know if there is a way to find out why a map service with custom SOE can’t be started.
I followed all the following steps listed in the tutorial:
1. Built SimpleSOE_interfaces.dll and SimpleSOE.dll
2. Registered SimpleSOE_interfaces with the tlb option and SimpleSOE.
3. Added SimpleSOE.dll to GAC
4. Ran RegisterSOE to register SimpleSOE
5. Placed the wsdl file in the XmlSchema folder
I created a map service and checked the SimpleSOE option in the capabilities tab. But the service couldn’t be started. There wasn’t much an error message, except the server object instance creation failed on all SOC machines. The verbose log didn’t show anything more than that. Full control was granted to all assembly files. I couldn’t think any way to find out what might be the problem.
Anything is helpful. Thanks!
sandeep / October 18th, 2010 15:58
hii,
actually i map service is publish at another location i.e on our server. so how can i debugg that one. thanks in advance
Dave / November 13th, 2010 1:38
Great post – thanks! I had been wondering how to best debug SOEs and this post was very helpful in doing so.
Giser – I had trouble with that sample as well (same steps and error as you). What I found was that if I register the DLL with the GAC, it does NOT work – when I skipped that step, the sample worked fine. I did still give my assembly a strong name and use the /codebase flag when running regasm – just skipped the step of adding to the GAC.
Kyle K. / April 26th, 2012 6:20
Hi –
I’m really new to AGS (been doing AO for 10 years). I’m really confused as to what step #3 is doing.
Where does the code from that window go?
I think I understand most of the rest of it but am at a loss for #3.
Thanks,
kyle
mapbutcher / April 26th, 2012 7:44
Kyle,
The code in step 3 provides an example of how you can connect to ArcGIS Server and call a method on your SOE.
If you’re writing an extension in a more recent version of ArcGIS Server i.e. v10 then I would not recommend connecting in this way. It is preferable to use either a SOAP or REST connection by implementing one of the ArcObjects SOAP or REST handlers i.e. IRestRequestHandler
Hope this helps
Simon