Windows Service Dies on Exception

  • Thread starter Thread starter jehugaleahsa
  • Start date Start date
J

jehugaleahsa

Hello:

I am working on a service. For the past month we have been simply
restarting the service daily (which defeats the point).

I have been putting some extra time into it today and have come to the
conclusion that a pop-up window is trying to open whenever an error
occurs.

However, the line of code that it dies on is inside of a try/catch. I
have super checked (dozens of times) that there is no way for an
exception to escape the bounds of my service.

Here is a summary of what appears in the EventViewer:

---
Application popup: ExpirationNotificationService.exe - Application
Error : The instruction at "0x77d016ab" referenced memory at
"0x77d016ab". The memory could not be "read".

Click on OK to terminate the program
---

I believe the reason why the code fails is totally in response to the
pop-up trying to open when the service is in the background. I have
found lots of articles about disabling the JIT debugger and they have
not solved my problem. Is there some setting on Server 2003 that
forces a pop-up during any type of error, even handled errors?

Thanks,
Travis
 
I have just found another article specifically to disable the
Application popup issue. However, now the service simply dies without
any errors being caught at all.

But, this means that an exception is definitely escaping my code,
however, I can't see how. Other people have commented that they have
had similar issues with try/catch not working. Some have suggested it
has something to do with threading.

Does anyone have any clue what could cause my try/catch to get skipped
over?

Thanks,
Travis
 
Travis,

Are you doing any work on any other threads? If so, are you catching
exceptions in those threads as well?

Have you considered using the Exception Handling Block in the Enterprise
Library to help shore up your exception handling? It will help with
exceptions on other threads, I believe.
 
Well, the only way I can see myself using a thread is if the
System.Timers.Timer class creates a new thread.

The method that gets called by the ElapsedEventHandler is completely
surrounded by a try/catch block. It is within the try/catch that the
error occurs.

It is as though the try/catch is ignored simply because it is being
executed on Windows Server 2003.
 
Well, the only way I can see myself using a thread is if the
System.Timers.Timer class creates a new thread.

The method that gets called by the ElapsedEventHandler is completely
surrounded by a try/catch block. It is within the try/catch that the
error occurs.

Ja. Is true when using System.Timers.Timer class:

The event handler must be reentrant, as the events are fired from
the threadpool, and a second event handler may be started before the
first one is completed.
There is a potential for a race condition because the elapsed event
may be fired even after the timer is stopped by a different
thread...example to avoid given in the Stop() method documentation of
MSDN...
It is as though the try/catch is ignored simply because it is being
executed on Windows Server 2003.

Not to sound flip, but what happens if you run it on WinXP? Have you
tried attaching an event to the
AppDomain.CurrentDomain.UnhandledException event and logging more
information about any unhandled exception that occurred?

The original exception looks like one that I usually get when I call
unmanaged code with either an invalid pointer or mangled data (i.e. i
either screwed up the marshalling, the pinning, or the function call
signature)
 
I have just found another article specifically to disable the
Application popup issue. However, now the service simply dies without
any errors being caught at all.

But, this means that an exception is definitely escaping my code,
however, I can't see how. Other people have commented that they have
had similar issues with try/catch not working. Some have suggested it
has something to do with threading.

Does anyone have any clue what could cause my try/catch to get skipped
over?

Thanks,
Travis


There is no exception thrown in this case, what you have here is an AV, the
instruction at xxxx is trying to read from xxxx, where xxxx is 0x77d016ab
(is it always the same address). It's nearly impossible to have a valid
instruction that reads from it's own location, so it looks like your service
has gone wild. Most of the time this is caused by unmanaged code buffer
overruns and stack overflows and heap corruptions, any chance that you call
into unmanaged code?
Anyway, the only sure way to handle this is by attaching a debugger.
Willy.
 
My code uses a crappy LDAP library that has all sorts of issues. My
concern is how to catch the exception that is generated. I have been
asked to use System.Threading.Timer instead. I will try this and see
how it deals.

I did try to use the UnhandledException event in AppDomain.Current,
however, it doesn't even get raised.
 
If the library is that unstable, then I would consider isolating it into
another process, or using COM+ to create an out-of-process application pool
which will keep your service from shutting down. This should allow you to
get a more trappable error that your service can process.
 
The folks here at work insist on using Novell's eDirectory rather than
ActiveDirectory. We are also running on old hardware and the SysAdmins
are fairly new to all the encryption/certificate stuff I am shoving on
them.

I have concealed as much as possible of Novell's LDAP code - I have a
nack for making libraries. Although, there simply isn't much you can
do when the underlying code has issues.

Using System.Threading.Timer seems to not have fixed my issue. Somehow
an exception is escaping my code; little trouble maker!
 
My code uses a crappy LDAP library that has all sorts of issues. My
concern is how to catch the exception that is generated. I have been
asked to use System.Threading.Timer instead. I will try this and see
how it deals.

I did try to use the UnhandledException event in AppDomain.Current,
however, it doesn't even get raised.

You can't trap this , it's not a managed exception , nor an unmanaged one.
The OS removes the process, simply because the instruction triggers a Access
Violation from which there's is no recovery possible.
Now before calling the library crappy, I would suggest you to inspect the
managed code PInvoke declarations, the arguments passed and the calling
convention as required by the exported functions are extremely important to
watch for. A wrong signature or a wrong calling convention declaration will
most certainly destroy the call stack at some point in time and may lead to
the problem you are seeing now.

Willy.
 
What is all this PInvoke stuff? My code doesn't deal with anything
like that. As far as I am concerned, everything is written in C# with
no hocus-pocus. I have no clue what the LDAP library does.

And why do non-services catch the exception just fine?
 
What is all this PInvoke stuff? My code doesn't deal with anything
like that. As far as I am concerned, everything is written in C# with
no hocus-pocus. I have no clue what the LDAP library does.

And why do non-services catch the exception just fine?


If the LDAP library is written in unmanaged code, you have to import the
library functions (DllImport) in order to enable transitioning via PInvoke
interop, if the LDAP library is it written in C#, then somehow it has to
call into unmanaged code and this is via the PInvoke interop layer, if the
library is written in "managed C++" or C++/CLI, it has to transition into
unmanaged code via PInvoke or C++ interop, this is no hocus-pocus, this is
how things are working in .NET. No matter how , when transitioning from/to
managed to unmanaged code you need to respect the calling conventions and
you need to watch for stack and heap corruption. Failing to do so will
sooner than later corrupt the process, depending where and how it fails will
possibly give you a clue by means of a managed exception or an SE or simply
a crash.
The address as shown in the error log is not pointing to an area of memory
where JIT compiled C# code will reside, more the address points to an area
of memory that can't be read, that means it's protected, that means there
should never be anything in there that the code needs to access, or
otherwise said the Instruction pointer has gone wild because of memory
corruption. There is no way to recover from this. What makes you think that
the the exception thrown by non-service has the same cause as this error,
how did you compare the exception when the service doesn't throw one? How
did the non-service exception looks like?

Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top