Kesalahan kunci loader


95

Saya membangun di C ++ dll, dengan menulis kode di C #.

Saya mendapatkan kesalahan, mengatakan

LoaderLock terdeteksi Pesan: Mencoba eksekusi terkelola di dalam OS Loader lock. Jangan mencoba menjalankan kode terkelola di dalam DllMain atau fungsi inisialisasi gambar karena hal itu dapat menyebabkan aplikasi macet.

Saya mencoba mencari apa sebenarnya arti kesalahan ini, tetapi saya menggambar artikel yang tidak berguna, kebanyakan mengatakan bahwa itu hanya peringatan, dan saya harus mematikannya di Visual Studio. Solusi lain tampaknya disebabkan oleh ITunes, atau masalah ini terjadi saat pemrograman dengan DirectX. Masalah saya tidak terkait dengan keduanya.

Adakah yang bisa menjelaskan, apa sebenarnya artinya ini?


Saya merasa dengan Anda, saya mendapat masalah yang sama, dan apa yang paling mengejutkan saya: dll saya bahkan bukan kode yang dikelola, jadi mengapa / bagaimana seharusnya menggunakan kode yang dikelola pada DllMain (tidak ada) ??
Sam

Saya mendapat peringatan ini saat mencoba melihat konten kumpulan data dalam mode debug. Saya menggunakan c #, itu terjadi dalam bentuk windows biasa.
Soenhay

Karena Anda tidak dapat mengetahui penyebabnya (seperti yang Anda komentari di jawaban atas) saya curiga ada dll yang Anda muat yang melakukan kejahatan.
John Thoits

Jawaban:


70

Anda perlu masuk ke menu Debug -> Pengecualian, buka Managed Debugging Assistants, temukan LoaderLock dan hapus centang

http://goo.gl/TGAHV


21
ya, ini adalah cara untuk mematikan peringatan; Tetapi bahkan setelah 2 tahun saya belum tahu persis mengapa itu terjadi.
Devdatta Tengshe

2
Ini terjadi pada saya membuka proyek lama di VS 2012
4imble

1
Saya dengan Anda @Kohan Saya juga membuka proyek yang lebih lama dan mendapat kesalahan. Saya telah menonaktifkan pengecualian tetapi ingin memahami apa yang dapat dilakukan untuk mencegah hal ini.
Pimenta

1
Jika saya menjalankan proyek sebagai Native debugging, dengan semua pengecualian pada default (reset semua), jendela debug menampilkan <mda: msg xmlns: mda = " schemas.microsoft.com/CLR/2004/10/mda "> <! - - Mencoba eksekusi terkelola di dalam OS Loader lock .... etc -> <mda: loaderLockMsg break = "true" /> </ mda: msg> VS kemudian menampilkan beberapa breakpoint selama urutan CTOR. Mematikan pengaturan LoaderLock tidak membantu. Bagi saya, saya harus mencentang opsi MDA teratas (untuk SEMUA MDA) lalu hapus centang opsi tingkat atas (tanpa MDA), lalu build + run. Ini tidak berhasil untuk kolega saya.
GilesDMiddleton

17
Ingin berbagi pembaruan di VS2015, Anda sekarang harus pergi ke Debug->Windows->Exception Settings. Sisanya sama denganManaged Debugging Assistants \ LoaderLock
jxramos

52

Ide umum dari kunci loader: Sistem menjalankan kode di DllMain di dalam kunci (seperti kunci sinkronisasi). Oleh karena itu, menjalankan kode non-sepele di dalam DllMain adalah "meminta jalan buntu", seperti yang dijelaskan di sini .

Pertanyaannya adalah, mengapa Anda mencoba menjalankan kode di dalam DllMain? Apakah penting bahwa kode ini dijalankan di dalam konteks DllMain atau dapatkah Anda menelurkan utas baru dan menjalankan kode di dalamnya, dan tidak menunggu kode untuk menyelesaikan eksekusi di dalam DllMain?

Saya percaya bahwa masalah dengan kode terkelola secara khusus, adalah menjalankan kode yang dikelola mungkin melibatkan memuat CLR dan semacamnya dan tidak ada yang tahu apa yang bisa terjadi di sana yang akan mengakibatkan kebuntuan ... Saya tidak akan mengindahkan saran "nonaktifkan peringatan ini "jika saya jadi Anda karena kemungkinan besar Anda akan menemukan aplikasi Anda macet secara tidak terduga dalam beberapa skenario.


4
Saya sedang mengerjakan aplikasi Direct3D. Ini adalah EXE. Namun, saya masih melihat kesalahan ini. Ada ide cara terbaik untuk memperbaikinya?
Agnel Kurian

18

UPDATE UNTUK .NET 4.0 DAN KERANGKA BARU-BARU INI

Ini adalah pertanyaan lama yang ditanyakan pada saat .Net 2.0, ketika dukungan untuk DLL mode campuran mengalami masalah inisialisasi yang serius, rentan terhadap kebuntuan acak. Pada .Net 4.0, inisialisasi DLL mode campuran telah berubah. Sekarang ada dua tahap inisialisasi yang terpisah:

  1. Inisialisasi asli, dipanggil di titik masuk DLL, yang mencakup penyiapan waktu jalan C ++ asli dan eksekusi metode DllMain Anda.
  2. Inisialisasi terkelola, dijalankan secara otomatis oleh pemuat sistem.

Karena langkah # 2 dilakukan di luar Loader Lock, tidak ada jalan buntu. Detailnya dijelaskan di Initialization of Mixed Assemblies .

Untuk memastikan perakitan mode campuran Anda dapat dimuat dari eksekusi asli, satu-satunya hal yang perlu Anda periksa adalah bahwa metode DllMain dideklarasikan sebagai kode asli. #pragma unmanagedbisa membantu di sini:

#pragma unmanaged

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

Penting juga bahwa kode apa pun yang mungkin dipanggil DllMain secara langsung atau tidak langsung juga tidak dikelola. Masuk akal untuk membatasi jenis fungsionalitas yang digunakan oleh DllMain sehingga Anda melacak semua kode yang dapat dijangkau dari DllMain dan memastikan semuanya dikompilasi #pragma unmanaged.

Compiler membantu sedikit dengan memberi Anda peringatan C4747 jika mendeteksi bahwa DllMain tidak dideklarasikan sebagai unmanaged:

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

Namun compiler tidak akan menghasilkan peringatan apa pun jika DllMain secara tidak langsung memanggil beberapa fungsi terkelola lainnya, jadi Anda perlu memastikan bahwa hal itu tidak akan pernah terjadi, jika tidak, aplikasi Anda dapat mengalami deadlock secara acak.


6

Tekan ctr d + e Kemudian Keluarkan Node Asisten Debugging yang Dikelola. Kemudian Hapus centang pada LoaderLock.

Semoga ini bisa membantu Anda.


Pintasannya adalah alt + d + x
Narayan

3
Pintasan sebenarnya bergantung pada konfigurasi yang telah Anda tentukan untuk digunakan saat pertama kali dijalankan. Tata letak pintasan C # adalah (Ctrl + D, E). (Anda juga dapat menetapkan kombinasi tombol apa pun ke fungsi ini di Opsi-> Lingkungan-> Keyboard.)
Adam LS

6

mohon ingatkan para pengguna VS2017 bahwa Anda perlu menonaktifkan " Exception helper " daripada " Exception Assistant " (sebelum VS2017) untuk mencegah kesalahan penguncian loader, yang jalur pengaturannya adalah Debug-> Exception . Baru saja berlari ke masalah ini dan menghabiskan 2 jam mencari solusi ...


Saya tidak memiliki "Pengecualian" di bawah "Debug". Saya memiliki Komunitas VS2017 15.8.4
Alex

@Alex, periksa Debug -> Windows -> Pengaturan Pengecualian, atau tekan Ctrl + Alt + E
mistika

4

Saya baru-baru ini mendapat kesalahan ini saat membuat instance dari COM-Object yang ditulis dalam kode asli:

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

Ini menyebabkan kesalahan yang dijelaskan. Sebuah "LoaderLock terdeteksi" -Exception dilemparkan.

Saya mengatasi kesalahan ini dengan membuat objek-contoh di utas tambahan:

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

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

Kesalahan dapat terjadi dengan objek Remotable (MarshalByRefObject), dan solusi ini tidak berfungsi untuk itu.
Matthieu

3

Saya sedang membangun C ++ CLR DLL (MSVS2015) yang harus melakukan panggilan ke DLL yang tidak dikelola dan menentukan kode yang tidak dikelola. Saya menggunakan #pragma managed dan #pragma unmanaged untuk mengontrol mode apa itu untuk area kode tertentu.

Dalam kasus saya, saya hanya meletakkan #pragma unmanaged di depan DllMain () saya dan ini memecahkan masalah. Sepertinya saya berpikir saya menginginkan versi terkelola DllMain ().



2

Jalur pengaturan dalam contoh visual studio 2017 saya adalah Debug -> Windows -> Pengaturan Pengecualian. Pengaturan pengecualian "jendela" muncul di grup tab bawah (sebagai lawan dari jendela terpisah), butuh beberapa saat untuk menyadarinya. Cari "loader".

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.