У меня есть простая функция внутри обработчика кликов, у которого есть блок catch try. Если я сделаю исключение в этом блоке catch catch, он успешно поймает исключение.UnmanagedFunctionPointer вызывает stackoverflow при использовании .NET 4.0, 3.5 works
Если я поместил вызов неуправляемой библиотеки DLL, прежде чем я вычеркнул исключение, исключение будет необработанным и не поймано.
Что такое незанятый вызов DLL, который может нарушить обработку исключений для моих программ?
Если я запустил программу в режиме отладки, она обнаруживает исключение, даже если «исключение для исключения» отключено для всех исключений. Приложение не сбой и работает как ожидалось.
Если я запустить программу как «начать без отладки» и ударили отладки, когда он выходит из строя я получаю следующее сообщение об ошибке «Stack код печенья приборостроения обнаружил стек на основе переполнения буфера»
редактировать: Он появляется переполнение стека прерывает обработку исключений
Я приложил упрощенную программу, которая вызывает сбой.
ISOConnection _comm; //This is instantiated at another time in the same thread
//C# test function that crashes when run without a debugger attached
bool DoMagic()
{
try
{
//if I uncomment this line the exception becomes unhandled and cannot be caught
//_comm.ConnectISO15765();
throw new Exception();
}
catch (Exception ex)
{
MessageBox.Show("Caught exception")
}
//Within ISOConnection class
public void ConnectISO15765(){
...
lock(syncLock){
uint returnCode = J2534Interface.PassThruConnect((uint)DeviceId, (uint)ProtocolID.ISO15765, (uint)ConnectFlag.NONE, (uint)BaudRate.ISO15765, ref ChannelId);
//C# UnmanagedFunctionPointer allocation code
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint PassThruConnect(uint deviceId, uint protocolId, uint flags, uint baudRate, ref uint channelId);
public PassThruConnect Connect;
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
m_pDll = NativeMethods.LoadLibrary(path);
...
pAddressOfFunctionToCall = NativeMethods.GetProcAddress(m_pDll, "PassThruConnect");
if (pAddressOfFunctionToCall != IntPtr.Zero)
Connect = (PassThruConnect)Marshal.GetDelegateForFunctionPointer(
pAddressOfFunctionToCall,
typeof(PassThruConnect));
//C++ function declaration
long PassThruConnect(unsigned long DeviceID, unsigned long ProtocolID, unsigned long Flags, unsigned long Baudrate, unsigned long *pChannelID);
UPDATE
Если я заменить вызов на UnmanagedFunctionPointer PassThurConnect с после аварии не происходит
[DllImport("op20pt32.dll", EntryPoint = "PassThruConnect", CallingConvention = CallingConvention.Cdecl)]
public static extern uint PassThruConnect2(uint deviceId, uint protocolId, uint flags, uint baudRate, ref uint channelId);
Есть ли что-то я не выполняет или я выступаю неправильно при назначении UnmanagedFunctionPointer, который приведет к тому, что отсутствие отладчика приведет к сбою stackoverflow?
Что еще незнакомец этот код появился, чтобы работать несколько недель назад. Основные изменения - это попытка catch в другом потоке, и я не использовал lock (syncLock). Все теперь в одном потоке, но тот же самый сбой произошел и при работе в BackgroundWorker.
UPDATE # 2 ПРОБЛЕМЫ SEMI-решаемые
Ok поэтому я отвалил через мои фиксации один за другим, пока он не работал. Что изменилось, я перешел от .NET 3.5 к .NET 4.0
.NET 3.5 не сбой, независимо от прикрепления отладчика или нет. Ошибка .NET 4.0, если отладчик не подключен. Чтобы исключить ошибку в моем коде, я просто удалил ConcurrentQueue для моего журнала (единственная функция 4.0, которую я использовал) и преобразовал мою текущую базу кода обратно в 3.5, и я не получаю эту ошибку.
Чтобы быть на 100% уверенным, что это проблема с 4.0, я преобразовал мою базу кода обратно в 4.0 из 3.5 и вышел из ConcurrentQueue вне (только что изменил параметры сборки и сделал пересоздание), а сбой StackOverflow вернулся.
Я бы предпочел использовать 4.0, любые идеи по отладке этой проблемы?
Редактировать: .NET 4.6.1 также врезается
UPDATE # 3 http://codenition.blogspot.com.au/2010/05/pinvokestackimbalance-in-net-40i-beg.html
Видимо pinvokestackimbalance в основном игнорируется в .NET 3.5, так что проблема все еще существует, она просто не врезаться мое заявление.
Добавление следующего кода в App.Config заставляет .NET восстанавливать стек при переходе к управляемому коду. Небольшой удар производительности, но он устранит проблему.
Несмотря на то, что это устраняет проблему, я хотел бы знать, что не так с моим неуправляемымFunctionPointer, чтобы вызвать проблему в первую очередь.
<configuration>
<runtime>
<NetFx40_PInvokeStackResilience enabled="1"/>
Edit: этот поток не дубликат, а другой удаляется ...
Есть несколько фатальных исключений, которые невозможно поймать с помощью .Net-кода. Я считаю, что один из них. Скорее всего, вы получили неверные обертки для взаимодействия, и стек смещен ... или собственный код просто плох. –
Итак, я добавил Debugger.Launch() непосредственно перед управляемым вызовом и выбрасывает исключение StackOverflow, это, без сомнения, нарушает обработку исключений. Почему это не происходит с отладчиком, подключенным с самого начала? – rolls
Хорошо, если я использую dllimport с тем же прототипом функции, я не получаю stackoverflow. Есть ли что-то еще, что мне нужно делать при использовании неуправляемых указателей? – rolls