I'm using TimeSetEvent and its callback function is working but after a few seconds it fails EVEN if the callback function does no work at all:
// Vars
private TimerEventHandler timerRef;
private uint timerId = 0;
//Later, where I use TimeSetEvent
timerRef = new TimerEventHandler(CallbackFunction);
timerId = timeSetEvent(200, 10, timerRef, UIntPtr.Zero, TIME_KILL_SYNCHRONOUS | TIME_PERIODIC);
Even with 200ms delay it's not working properly.
private void CallbackFunction(uint id, uint msg, UIntPtr userCtx, UIntPtr uIntPtr, UIntPtr intPtr)
{
// Even if this is empty, it will fail
}
I either get NullReferenceException(most of the times) or AccessViolationException (occasionally). I suspect both coming from the same problem.
Funny thing, I have exactly the same structure in another class and it works. I copied that class and here... It doesn't. I get this error.
I don't understand why it's not working (and in the other class it does) and how to solve it.
PD: timerId returns an integer different than 0. I don't understand where this null comes frmo, if I comment TimerId = TimeSetEvent... Code won't fail.
After couple of days with my workmate reviewing more and more code we found the problem. Have to say the question didn't have enough information to solve it, but we couldn't know. It's very complex program and we couldn't imagine we needed code from other classes.
The code above is in Class B. This is called from Class A. Turns out Class A is destroyed occasionally and as TimeSetEvent is pinvoked (unmanaged) it carries on working. Therefore, when it tries to look for the callback function it has been disposed along with all contents from Class B and it gives a null reference exception.
The solution is to implement a method in Class B that kills the timer before removing Class A. Then, it will be safe to delete Class A and Class B won't make the application crash.
Related
I have code in C++, which I will call from C# via interop mechanism.
In my C++ code, this is my class structure
extern "C" struct __declspec(dllexport) LegList
{
SimpleList simple_List;
int* inputList;
};
This is my C# code:
[StructLayout(LayoutKind.Sequential)]
public struct LegList
{
SimpleList simple_List;
public IntPtr inputList;
}
The inputList is not used anywhere in C#.
My questions are:
In C++ code, should I set inputList to NULL?
If I set it to NULL, how should I best set it to avoid bugs? Should I use inputList=0, or inputList=NULL, or inputList=(int*)malloc(0)?
If I don't set it, or if I set it wrongly, what are the consequences? Will some very hard to diagnose bug appears? What I am afraid is that if I don't set it correctly, some machines might run the code fine, others might not. And when the program stops working, it will stop at a point much later, resulting in a very hard to diagnose problem for us, such as AccessViolationException.
All in all, if I set it to inputList=(int*)malloc(0), or if I don't set it at all, will the program crash at a different place at a later time, in a very unpredictable and inconsistent manner, depending on which machine the code is running on?
Will assigning a pointer to (int*)malloc(0) causes unpredictable crash? How should I properly set an unused pointer?
Simply set it to NULL or, if your compiler supports it, to nullptr. This makes it clear that it doesn't point to anything useful.
So either inputList=NULL or inputList=nullptr.
Obviously, not setting it at all, is the worst thing to do. If there is any code that uses it, it will behave unpredictably.
I'm not sure, why one would want to do inputList=(int*)malloc(0).
In a WCF being run from IIS I have this code (well something similar).
public static class Test
{
public static int Method(int x, int y)
{
int p = 10;
int r = p * x * y;
return r;
}
}
This method can then in theory be called from 1 million requests from 1 million different users simultaneously.
I have an argument discussion with a colleague where my stand point is that each instance of this method call is separate and will never cause data corruption between calls. This is supported by this thread: C# : What if a static method is called from multiple threads?
My colleague however claims that IIS and WCF are a special kind of monster that can cache and start/stop calls in all kinds of weird places so that in practice these calls actually can interfer with one another.
The example he made was that if one call is inside the method and another one comes in with new paramaters then the int x and int y paramater variables values could potentially be replaced for the already ongoing call.
His stand point is NEVER use static methods / classes in anything IIS / WCF related.
I haven't been able to find any solid documentation that supports either case, anyone care to throw some well documentet arguments at this?
This is not the case.
.NET code does not have the ability to interfere with other code's execution. For example it cannot cache calls or stop them or cause local variables to be shared when they are not. The CLI specification clearly prescribes the way static methods are executed.
Even if the authors of the WCF framework wanted to do such a thing they could not. (At least not without CLR runtime support.)
If it suddenly was no longer safe to call static methods (!) what piece of code could still run?! You couldn't even call string.Join.
WCF does no such thing. Your colleague needs to provide some evidence now for what he has claimed. Such outrageous claims often arise from a confusing experience made by that person. Maybe he fixed a bug by making a method non-static and doing something else without realizing it. Now he beliefs that the static property was the cause for the bug. This can lead to superstitious beliefs.
C#, VS 2010
I need to determine if a float value is NaN.
Testing a float for NaN using
float.IsNaN(aFloatNumber)
crashes with a stack overflow.
So does
aFloatNumber.CompareTo(float.NaN).
The following does not crash, but it's not useful as it returns NaN regardless:
aFloatNumber - float.NaN
A search for "stack overflow" returns results about this website instead of results about an actual stack overflow, so I can't find relevant answers.
Why is my application going into a stack overflow when testing for NaN?
Edit: the call stack:
Edit: it's clearly something in my code: this statement:
bool aaa = float.IsNaN(float.NaN);
works OK in the constructor of the application, right after InitializeComponent();
works OK in the constructor of theclass for a custom control, right after InitializeComponent();
but crashes in an event handler inside the class for a custom control.
So, this is what I am doing:
Abstract Custom control: public abstract partial class ConfigNumberBaseBox : TextBox
has a Validating event handler ValidateTextBoxEntry
ValidateTextBoxEntry is defined inside the ConfigNumberBaseBox class
Custom control that inherits from ConfigNumberBaseBox : public partial class ConfigTemperBox : ConfigNumberBaseBox
Run the app
When I finish editing a ConfigTemperBox control, ValidateTextBoxEntry is called
ValidateTextBoxEntry runs fine until it encounters float.IsNaN
stack overflow
Edit:
Debug.WriteLine() shows that the code is executed only once: no recursion.
Edit:
This works:
float fff = 0F;
int iii = fff.CompareTo(float.PositiveInfinity);
This crashes:
float fff = 0F;
int iii = fff.CompareTo(float.NaN);
works OK in the constructor of theclass for a custom control
This is the only real hint towards the underlying problem. Code that runs on a thread can manipulate two stacks inside the processor. One is the normal one that everybody knows about and gave this web site its name. There is however another one, well hidden inside the FPU (Floating Point Unit). It stores intermediate operand values while making floating point calculations. It is 8 levels deep.
Any kind of mishap inside the FPU is not supposed to generate runtime exceptions. The CLR assumes that the FPU is configured with its defaults for the FPU control word, the hardware exceptions it can generate are supposed to be disabled.
That does have a knack for going wrong when your program uses code that came from the 1990s, back when enabling FPU exceptions still sounded like a good idea. Code generated by Borland tooling are notorious for doing this for example. Its C runtime module reprograms the FPU control word and unmasks the hardware exceptions. The kind of exceptions you can get for that can be very mysterious, using NaN in your code is a good way to trigger such an exception.
This should be at least partially visible with the debugger. Set a breakpoint on the "still good" code and use the Debug + Windows + Registers debugger window. Right-click it and select "Floating point". You'll see all of the registers that are involved with floating point calculations, ST0 through ST7 are the stack registers for example. The important one here is marked CTRL, its normal value in a .NET process is 027F. The last 6 bits in that value are the exception masking bits (0x3F), all turned on to prevent hardware exceptions.
Single step through the code and the expectation is that you see the CTRL value change. As soon as it does then you'll have found the evil code. If you enable unmanaged debugging then you should also see the load notification in the Output window and see it appear in the Debug + Windows + Module window.
Undoing the damage that the DLL did is fairly awkward. You'd have to pinvoke _control87() in msvcrt.dll for example to restore the CTRL word. Or a simple trick that you can use, you can intentionally throw an exception. The exception handling logic inside the CLR resets the FPU control word. So with some luck, this kind of code is going to solve your problem:
InitializeComponent();
try { throw new Exception("Please ignore, resetting FPU"); }
catch {}
You may have to move it, next best guess is the Load event. The debugger should tell you where.
I just wrote an example to reproduce the error:
1. Create a native C/C++ DLL which exports this function:
extern "C" __declspec(dllexport) int SetfloatingControlWord(void)
{
//unmask all the floating excetpions
int err = _controlfp_s(NULL, 0, _MCW_EM);
return err;
}
2. Create a C# console program, which call the function SetfloatingControlWord, after that, do some floating operation such as NaN compare, then it leads to stack overflow.
[DllImport("floatcontrol.dll")]
public static extern Int32 SetfloatingControlWord();
static void Main(string[] args)
{
int n = SetfloatingControlWord();
float fff = 0F;
int iii = fff.CompareTo(float.NaN);
}
I encountered the same problem years ago, also, I noticed that after an .NET exception throws, everything works fine, it took me a while to figure out why and trace the code which changed the FPU.
As the doc of function _controlfp_s says: By default, the run-time libraries mask all floating-point exceptions. The common language runtime (CLR) only supports the default floating-point precision, so CLR doesn't handle these kind exceptions.
As MSDN says:By default, the system has all FP exceptions turned off. Therefore, computations result in NAN or INFINITY, rather than an exception.
After NaN was introduced in IEEE 754 1985, it suppose that application software no longer need to handle the floating point exceptions.
The solution:
First of all, thank you to #Matt for pointing me in the right direction, and #Hans Passant for providing the workaround.
The application talks to a CAN-USB adapter from Chinese manufacturer QM_CAN.
The problem is in their driver.
The DLL statements and Driver import:
// DLL Statement
IntPtr QM_DLL;
TYPE_Init_can Init_can;
TYPE_Quit_can Quit_can;
TYPE_Can_send Can_send;
TYPE_Can_receive Can_receive;
delegate int TYPE_Init_can(byte com_NUM, byte Model, int CanBaudRate, byte SET_ID_TYPE, byte FILTER_MODE, byte[] RXF, byte[] RXM);
delegate int TYPE_Quit_can();
delegate int TYPE_Can_send(byte[] IDbuff, byte[] Databuff, byte FreamType, byte Bytes);
delegate int TYPE_Can_receive(byte[] IDbuff, byte[] Databuff, byte[] FreamType, byte[] Bytes);
// Driver
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32.dll")]
static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
The call to the offending code, including Hans' workaround:
private void InitCanUsbDLL() // Initiate the driver for the CAN-USB dongle
{
// Here is an example of dynamically loaded DLL functions
QM_DLL = LoadLibrary("QM_USB.dll");
if (QM_DLL != IntPtr.Zero)
{
IntPtr P_Init_can = GetProcAddress(QM_DLL, "Init_can");
IntPtr P_Quit_can = GetProcAddress(QM_DLL, "Quit_can");
IntPtr P_Can_send = GetProcAddress(QM_DLL, "Can_send");
IntPtr P_Can_receive = GetProcAddress(QM_DLL, "Can_receive");
// The next line results in a FPU stack overflow if float.NaN is called by a handler
Init_can = (TYPE_Init_can)Marshal.GetDelegateForFunctionPointer(P_Init_can, typeof(TYPE_Init_can));
// Reset the FPU, otherwise we get a stack overflow when we work with float.NaN within a event handler
// Thanks to Matt for pointing me in the right direction and to Hans Passant for this workaround:
// http://stackoverflow.com/questions/25205112/testing-for-a-float-nan-results-in-a-stack-overflow/25206025
try { throw new Exception("Please ignore, resetting FPU"); }
catch { }
Quit_can = (TYPE_Quit_can)Marshal.GetDelegateForFunctionPointer(P_Quit_can, typeof(TYPE_Quit_can));
Can_send = (TYPE_Can_send)Marshal.GetDelegateForFunctionPointer(P_Can_send, typeof(TYPE_Can_send));
Can_receive = (TYPE_Can_receive)Marshal.GetDelegateForFunctionPointer(P_Can_receive, typeof(TYPE_Can_receive));
}
}
The reason that the application crashed when a reference was made to float.NaN in the event handler and not in the constructor was a simple matter of timing: the constructor is called before InitCanUsbDLL(), but the event handler was called long after InitCanUsbDLL() corrupted the FPU registers.
So I have a native 3rd party C++ code base I am working with (.lib and .hpp files) that I used to build a wrapper in C++/CLI for eventual use in C#.
I've run into a particular problem when switching from Debug to Release mode, in that I get an Access Violation Exception when a callback's code returns.
The code from the original hpp files for callback function format:
typedef int (*CallbackFunction) (void *inst, const void *data);
Code from the C++/CLI Wrapper for callback function format:
(I'll explain why I declared two in a moment)
public delegate int ManagedCallbackFunction (IntPtr oInst, const IntPtr oData);
public delegate int UnManagedCallbackFunction (void* inst, const void* data);
--Quickly, the reason I declared a second "UnManagedCallbackFunction" is that I tried to create an "intermediary" callback in the wrapper, so the chain changed from Native C++ > C# to a version of Native C++ > C++/CLI Wrapper > C#...Full disclosure, the problem still lives, it's just been pushed to the C++/CLI Wrapper now on the same line (the return).
And finally, the crashing code from C#:
public static int hReceiveLogEvent(IntPtr pInstance, IntPtr pData)
{
Console.WriteLine("in hReceiveLogEvent...");
Console.WriteLine("pInstance: {0}", pInstance);
Console.WriteLine("pData: {0}", pData);
// provide object context for static member function
helloworld hw = (helloworld)GCHandle.FromIntPtr(pInstance).Target;
if (hw == null || pData == null)
{
Console.WriteLine("hReceiveLogEvent: received null instance pointer or null data\n");
return 0;
}
// typecast data to DataLogger object ptr
IntPtr ip2 = GCHandle.ToIntPtr(GCHandle.Alloc(new DataLoggerWrap(pData)));
DataLoggerWrap dlw = (DataLoggerWrap)GCHandle.FromIntPtr(ip2).Target;
//Do Logging Stuff
Console.WriteLine("exiting hReceiveLogEvent...");
Console.WriteLine("pInstance: {0}", pInstance);
Console.WriteLine("pData: {0}", pData);
Console.WriteLine("Setting pData to zero...");
pData = IntPtr.Zero;
pInstance = IntPtr.Zero;
Console.WriteLine("pData: {0}", pData);
Console.WriteLine("pInstance: {0}", pInstance);
return 1;
}
All writes to the console are done and then we see the dreaded crash on the return:
Unhandled exception at 0x04d1004c in
helloworld.exe: 0xC0000005: Access
violation reading location 0x04d1004c.
If I step into the debugger from here, all I see is that the last entry on the call stack is: > "04d1004c()" which evaluates to a decimal value of: 80805964
Which is only interesting if you look at the console which shows:
entering registerDataLogger
pointer to callback handle: 790848
fp for callback: 2631370
pointer to inst: 790844
in hReceiveLogEvent...
pInstance: 790844
pData: 80805964
exiting hReceiveLogEvent...
pInstance: 790844
pData: 80805964
Setting pData to zero...
pData: 0
pInstance: 0
Now, I know that between debug and release some things are quite different in the Microsoft world. I am, of course worried about byte padding and initialization of variables, so if there is something I am not providing here, just let me know and I'll add to the (already long) post. I also think the managed code may NOT be releasing all ownership and then the native C++ stuff (which I don't have the code for) may be trying to delete or kill off the pData object, thus crashing the app.
More full disclosure, it all works fine (seemingly) in Debug mode!
A real head scratch issue that would appreciate any help!
I think the stack got crushed because of mismatching calling conventions:
try out to put the attribute
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
on the callback delegate declaration.
This doesn't directly answer your question, but it may lead you in the right direction as far as debug mode okay vs. release mode not okay:
Since the debugger adds a lot of record-keeping information to the stack, generally padding out the size and layout of my program in memory, I was “getting lucky” in debug mode by scribbling over 912 bytes of memory that weren’t very important. Without the debugger, though, I was scribbling on top of rather important things, eventually walking outside of my own memory space, causing Interop to delete memory it didn’t own.
What is the definition of DataLoggerWrap? A char field may be too small for the data you are receiving.
I'm not sure what your are trying to achieve.
A few points:
1) The garbage collector is more aggressive in release mode so with bad ownership the behaviour you describe is not uncommon.
2) I don't understands what the below code is trying to do?
IntPtr ip2 = GCHandle.ToIntPtr(GCHandle.Alloc(new DataLoggerWrap(pData)));
DataLoggerWrap dlw = (DataLoggerWrap)GCHandle.FromIntPtr(ip2).Target;
You use GCHandle.Alloc to lock an instance of DataLoggerWrap in memory, but then you never pass it out to unmanaged - so why do you lock it?
You also never free it?
The second line then grabs back a reference - why the circular path? why the reference - you never use it?
3) You set the IntPtrs to null - why? - this will have no effect outside of the function scope.
4) You need to know what the contract of the callback is. Who owns pData the callback or the calling function?
I'm with #jdehaan, except CallingConvetion.StdCall could be the answer, especially when the 3rd party lib is written in BC++, for example.
I have this piece of code (from the Nokia PC connectivity 3.2 example code, in C#):
DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo =
new DAContentAccessDefinitions.CA_FOLDER_INFO();
folderInfo.iSize = Marshal.SizeOf(folderInfo); //(32)
IntPtr bufItem = Marshal.AllocHGlobal(folderInfo.iSize);
//I often get a AccessViolationException on the following line
Marshal.StructureToPtr(folderInfo, bufItem, true);
If I run GC.Collect() at the start of this, then I don't get an AccessViolationException. But I don't want to slow down this function unless necessary. I've tried putting GC.Keepalive in various places, but without success.
CA_FOLDER_INFO is defined as:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct CA_FOLDER_INFO
{
public int iSize;
public int iFolderId;
public int iOptions;
public string pstrName;
public string pstrPath;
public int iSubFolderCount;
public IntPtr pSubFolders;
public IntPtr pParent;
}
I don't, in this instance, require either of the strings, and changing their definitions to IntPtr seems to make the exception go away.
What is going on here, and what is the correct way to prevent the exception?
Your problem is that you're passing true to Marshal.StructureToPtr so it attempts to free the two string pointers (which are sometimes invalid). You need to pass false in this instance since you just allocated that memory on the heap. (i.e. there's nothing to free there).
Are you sure Marshal.Sizeof(bufItem) and Marshal.Sizeof(folderInfo) are the same?
And, maybe the fact that you aren't initializing the strings? Since you say you don't get the error when they are IntPtr (which defaults to IntPtr.Zero), I'd try setting them both to empty strings before you try marshaling the buffer item.
[Edit]
Maybe you should try pinning the buffer handle, and marshaling that to the structure, rather than vis versa. Something like this:
DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo;
GCHandle pinnedHandle = GCHandle.Alloc(buffItem, GCHandleType.Pinned);
folderInfo = (DAContentAccessDefinitions.CA_FOLDER_INFO)Marshal.PtrToStructure(pin.AddrOfPinnedObject(), typeof(DAContentAccessDefinitions.CA_FOLDER_INFO));
pin.Free();
//folderInfo should contain the data from buffItem
Use the fixed keyword to get a pointer to your original folderInfo.
It could be that unmanaged resources aren't being released by something. Check to see if anything you're using implements IDisposable and if so, wrap it in a using { } block.