Yükleyici kilit hatası


95

C # ile kod yazarak C ++ dll üzerinde inşa ediyorum.

Bir hata alıyorum

LoaderLock algılandı Mesaj: OS Loader kilidi içinde yönetilen yürütme girişiminde bulunuluyor. Yönetilen kodu bir DllMain veya görüntü başlatma işlevi içinde çalıştırmayı denemeyin çünkü bunu yapmak uygulamanın askıda kalmasına neden olabilir.

Bu hatanın tam olarak ne anlama geldiğini araştırmayı denedim, ancak anlamsız makaleler çiziyorum, çoğunlukla bunun sadece bir uyarı olduğunu ve bunu Visual Studio'da kapatmam gerektiğini söylüyorum. Diğer çözümler ITunes'dan veya DirectX ile programlama yaparken ortaya çıkan bu sorundan kaynaklanıyor gibi görünüyor. Benim sorunum hiçbiriyle bağlantılı değil.

Bunun gerçekte ne anlama geldiğini kimse açıklayabilir mi?


Seninle hissediyorum, aynı problemi yaşıyorum ve beni en çok şaşırtan şey: benim dll kodum yönetilen kod bile değil, öyleyse neden / nasıl (var olmayan) DllMain'de yönetilen kod kullanması gerekiyor?
Sam

Hata ayıklama modunda bir veri kümesinin içeriğini görüntülemeye çalışırken bu uyarıyı aldım. C # kullanıyorum, bu normal bir pencere biçiminde oldu.
Soenhay

Nedeni bulamadığınız için (en üstteki cevapta yorumladığınız gibi) Suçu işleyen yüklediğiniz bir dll olduğundan şüpheleniyorum.
John Thoits

Yanıtlar:


70

Hata Ayıklama -> İstisnalar menüsüne gitmeniz, Yönetilen Hata Ayıklama Yardımcılarını açmanız, Yükleyici Kilidini bulmanız ve işaretini kaldırmanız gerekir

http://goo.gl/TGAHV


21
evet, uyarıyı kapatmanın yolu budur; Ancak 2 yıl sonra bile tam olarak neden olduğunu anlamadım.
Devdatta Tengshe

2
Bu VS 2012'de eski bir projeyi açarken başıma geldi
4imble

1
Seninleyim @Kohan Ben de eski bir proje açtım ve hatayı aldım. İstisnayı devre dışı bıraktım ancak bunu önlemek için neler yapılabileceğini anlamak istiyorum.
Pimenta

1
Projeyi varsayılan olarak tüm istisnalarla (tümünü sıfırla) Yerel hata ayıklama olarak çalıştırırsam, hata ayıklama penceresinde <mda: msg xmlns: mda = " schemas.microsoft.com/CLR/2004/10/mda "> <! - - İşletim Sistemi Yükleyici kilidi içinde yönetilen yürütme denemesi .... etc -> <mda: loaderLockMsg break = "true" /> </ mda: msg> VS, CTOR dizisi sırasında birden çok kesme noktası sunar. LoaderLock ayarının kapatılması yardımcı olmuyor. Benim için, en üstteki MDA seçeneğini işaretlemeliydim (TÜM MDA için), ardından en üst düzey seçeneğin işaretini kaldırmam (MDA yok), sonra inşa et + çalıştır. Bu meslektaşım için işe yaramadı.
GilesDMiddleton

17
VS2015'te bir güncelleme paylaşmak istediniz, şimdi gitmeniz gerekiyor Debug->Windows->Exception Settings. Gerisi ile aynıManaged Debugging Assistants \ LoaderLock
jxramos

52

Yükleyici kilidinin genel fikri: Sistem, DllMain'deki kodu bir kilit içinde çalıştırır (senkronizasyon kilidi gibi). Bu nedenle, DllMain içinde önemsiz olmayan kod çalıştırmak, burada açıklandığı gibi "kilitlenme istemektir" .

Soru, neden DllMain içinde kod çalıştırmaya çalışıyorsunuz? Bu kodun DllMain bağlamında çalışması çok önemli mi yoksa yeni bir iş parçacığı oluşturabilir ve içindeki kodu çalıştırabilir ve kodun DllMain içinde yürütmeyi bitirmesini beklemeyebilir misiniz?

Özellikle değiştirilmiş kodla ilgili sorunun, yönetilen kod çalıştırmanın CLR'yi yüklemeyi içerebileceğine ve bunun bir çıkmaza neden olacak ne olabileceğini bilmemeye inanıyorum ... "Bu uyarıyı devre dışı bırakın "Yerinde olsaydım, çünkü büyük olasılıkla uygulamalarınızın bazı senaryolarda beklenmedik şekilde takıldığını göreceksiniz.


4
Direct3D uygulaması üzerinde çalışıyorum. Bu bir EXE. Ancak yine de bu hatayı görüyorum. Bunu en iyi şekilde düzeltmek için bir fikriniz var mı?
Agnel Kurian

18

NET 4.0 İÇİN GÜNCELLEME VE DAHA SON ÇERÇEVELER

Bu, .Net 2.0 zamanında sorulan eski bir sorudur, karma mod DLL desteği ciddi başlatma sorunları yaşadığında, rastgele kilitlenmelere meyilliydi. .Net 4.0'dan itibaren, karma mod DLL'lerin başlatılması değişmiştir. Şimdi iki ayrı başlatma aşaması var:

  1. DllMain yönteminizin yerel C ++ çalışma zamanı kurulumunu ve yürütülmesini içeren DLL'nin giriş noktasında çağrılan yerel başlatma.
  2. Yönetimli başlatma, sistem yükleyici tarafından otomatik olarak yürütülür.

2. adım, Yükleyici Kilidinin dışında gerçekleştirildiğinden, herhangi bir kilitlenme yoktur. Ayrıntılar, Karma Meclislerin Başlatma bölümünde açıklanmıştır .

Karma mod derlemenizin yerel bir yürütülebilir dosyadan yüklenebilmesini sağlamak için, kontrol etmeniz gereken tek şey DllMain yönteminin yerel kod olarak bildirilmesidir. #pragma unmanagedburada yardımcı olabilir:

#pragma unmanaged

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
    )
{
    ... // your implementation here
}

DllMain'in doğrudan veya dolaylı olarak çağırabileceği herhangi bir kodun da yönetilmemesi önemlidir. DllMain tarafından kullanılan işlevsellik türünü sınırlamak mantıklıdır, böylece DllMain'den erişilebilen tüm kodları izleyebilir ve tümünün derlendiğinden emin olabilirsiniz #pragma unmanaged.

Derleyici, DllMain'in yönetilmeyen olarak bildirilmediğini algılarsa C4747'yi uyararak size biraz yardımcı olur:

1>  Generating Code...
1>E:\src\mixedmodedll\dllmain.cpp : warning C4747: Calling managed 'DllMain': Managed code may not be run under loader lock, including the DLL entrypoint and calls reached from the DLL entrypoint

Ancak, DllMain dolaylı olarak başka bir yönetilen işlevi çağırırsa, derleyici herhangi bir uyarı üretmez, bu nedenle bunun asla gerçekleşmediğinden emin olmanız gerekir, aksi takdirde uygulamanız rastgele kilitlenebilir.


6

Ctr d + e'ye basın Sonra Yönetilen Hata Ayıklama Yardımcıları Düğümünü Harcayın. Ardından LoaderLock'un işaretini kaldırın.

Umarım bu sana yardımcı olur.


Kısayol alt + d + x
Narayan

3
Kısayol aslında ilk çalıştırma sırasında kullanmak üzere belirttiğiniz konfigürasyona bağlıdır. C # kısayol düzeni (Ctrl + D, E) şeklindedir. (Ayrıca Seçenekler-> Ortam-> Klavye'de bu işleve herhangi bir tuş kombinasyonu atayabilirsiniz.)
Adam LS

6

VS2017 kullanıcılarına yükleyici kilit hatasını önlemek için " istisna asistanı " yerine (VS2017'den önce) " istisna yardımcısını " devre dışı bırakmanız gerektiğini lütfen hatırlatın , bu ayar yolu Debug-> Exception'dır . Sadece bu problemle karşılaştım ve çözüm aramak için 2 saat harcadım ...


"Hata Ayıkla" altında "İstisna" yok. VS2017 Topluluğum 15.8.4 var
Alex

@Alex, Hata Ayıklama'yı kontrol edin -> Windows -> İstisna Ayarları veya Ctrl + Alt + E
mistika

4

Yakın zamanda yerel kodda yazılmış bir COM-Nesnesi örneğini oluştururken bu hatayı aldım:

m_ComObject = Activator.CreateInstance(Type.GetTypeFromProgID("Fancy.McDancy"));

Bu, açıklanan hataya yol açtı. Bir "LoaderLock algılandı" -Exception oluşturuldu.

Ekstra bir iş parçacığında nesne örneğini oluşturarak bu hatayı aştım:

ThreadStart threadRef = new ThreadStart(delegate { m_ComObject = Activator.CreateInstance(Type.GetTypeFromProgID("Fancy.McDancy")); });
Thread myThread = new Thread(threadRef);

myThread.Start();
myThread.Join(); // for synchronization

Hata, Remotable nesnelerde (MarshalByRefObject) olabilir ve bu çözüm bunlar için çalışmaz.
Matthieu

3

Yönetilmeyen bir DLL'ye çağrı yapmak ve yönetilmeyen kodu tanımlamak zorunda olan bir C ++ CLR DLL (MSVS2015) oluşturuyorum. Kodun belirli bir alanı için hangi modda olduğunu kontrol etmek için #pragma managed ve #pragma unmanaged kullanıyorum.

Benim durumumda, #pragma'yı DllMain () cihazımın önüne yönetilmeyen koydum ve bu sorunu çözdü. DllMain () 'in yönetilen bir sürümünü istediğimi düşünüyor gibiydi.



2

Visual studio 2017 örneğimdeki ayar yolu Debug -> Windows -> Exception Settings'dir. Alt sekme grubunda gösterilen istisna ayarları "penceresi" (ayrı bir pencerenin aksine), bunu fark etmem biraz zaman aldı. "Yükleyici" arayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.