Lỗi khóa bộ nạp


95

Tôi đang xây dựng trên C ++ dll, bằng cách viết mã bằng C #.

Tôi nhận được một lỗi, nói rằng

LoaderLock đã được phát hiện Thông báo: Đang cố gắng thực thi được quản lý bên trong khóa OS Loader. Không cố gắng chạy mã được quản lý bên trong DllMain hoặc chức năng khởi tạo hình ảnh vì làm như vậy có thể khiến ứng dụng bị treo.

Tôi đã cố gắng tìm hiểu chính xác lỗi này có nghĩa là gì, nhưng tôi đang vẽ các bài báo vô nghĩa, chủ yếu nói rằng đó chỉ là một cảnh báo và tôi nên tắt nó trong Visual Studio. Các giải pháp khác dường như là do iTunes hoặc sự cố này xảy ra khi lập trình với DirectX. Vấn đề của tôi được kết nối với cả hai.

Ai có thể giải thích, điều này thực sự có nghĩa là gì?


Tôi cảm thấy với bạn, tôi cũng gặp phải vấn đề tương tự, và điều làm tôi ngạc nhiên nhất: dll của tôi thậm chí không phải là mã được quản lý, vậy tại sao / làm thế nào nó được sử dụng mã được quản lý trên DllMain (không tồn tại) ??
Sam

Tôi nhận được cảnh báo này khi cố gắng xem nội dung của tập dữ liệu ở chế độ gỡ lỗi. Tôi đang sử dụng c #, nó xảy ra ở dạng cửa sổ thông thường.
Soenhay

Vì bạn không thể tìm ra nguyên nhân (như bạn đã nhận xét trong câu trả lời trên cùng), tôi nghi ngờ rằng có một dll bạn đang tải đang phạm tội.
John Thoits

Câu trả lời:


70

bạn cần vào menu Gỡ lỗi -> Ngoại lệ, mở Hỗ trợ gỡ lỗi được quản lý, tìm LoaderLock và bỏ chọn

http://goo.gl/TGAHV


21
vâng, đây là cách để tắt cảnh báo; Nhưng ngay cả sau 2 năm tôi vẫn chưa tìm ra chính xác tại sao nó lại xảy ra.
Devdatta Tengshe

2
Điều này đã xảy ra với tôi khi mở một dự án cũ trong VS 2012
4imble

1
Tôi với bạn @Kohan Tôi cũng đã mở một dự án cũ hơn và gặp lỗi. Tôi đã vô hiệu hóa ngoại lệ nhưng muốn hiểu những gì có thể được thực hiện để ngăn chặn điều này.
Pimenta

1
Nếu tôi chạy dự án dưới dạng Gỡ lỗi gốc, với tất cả các ngoại lệ theo mặc định (đặt lại tất cả), cửa sổ gỡ lỗi sẽ hiển thị <mda: msg xmlns: mda = " schemas.microsoft.com/CLR/2004/10/mda "> <! - - Cố gắng thực thi được quản lý bên trong khóa OS Loader .... vv -> <mda: loaderLockMsg break = "true" /> </ mda: msg> VS sau đó hiển thị nhiều điểm ngắt trong chuỗi CTOR. Tắt cài đặt LoaderLock không giúp được gì. Đối với tôi, tôi phải đánh dấu vào tùy chọn MDA cao nhất (cho TẤT CẢ MDA), sau đó bỏ chọn tùy chọn cấp cao nhất (cho không MDA), sau đó xây dựng + chạy. Điều này không hiệu quả với đồng nghiệp của tôi.
GilesDMiddleton

17
Muốn chia sẻ bản cập nhật trong VS2015, bây giờ bạn cần phải truy cập Debug->Windows->Exception Settings. Phần còn lại tương tự vớiManaged Debugging Assistants \ LoaderLock
jxramos

52

Ý tưởng chung về khóa bộ nạp: Hệ thống chạy mã trong DllMain bên trong một khóa (như khóa đồng bộ hóa). Do đó, chạy mã không tầm thường bên trong DllMain là "yêu cầu bế tắc", như được mô tả ở đây .

Câu hỏi đặt ra là tại sao bạn lại cố chạy mã bên trong DllMain? Điều quan trọng là mã này chạy bên trong ngữ cảnh của DllMain hay bạn có thể tạo ra một luồng mới và chạy mã trong đó và không đợi mã kết thúc thực thi bên trong DllMain?

Tôi tin rằng vấn đề cụ thể với mã manged, là việc chạy mã được quản lý có thể liên quan đến việc tải CLR và tương tự như vậy và không biết điều gì có thể xảy ra ở đó dẫn đến bế tắc ... Tôi sẽ không chú ý đến lời khuyên "hãy tắt cảnh báo này "nếu tôi là bạn vì rất có thể bạn sẽ thấy các ứng dụng của mình bị treo bất ngờ trong một số trường hợp.


4
Tôi đang làm việc trên một ứng dụng Direct3D. Đây là một EXE. Tuy nhiên, tôi vẫn thấy lỗi này. Bất kỳ ý tưởng làm thế nào để khắc phục điều này tốt nhất?
Agnel Kurian 16/10/08

18

CẬP NHẬT CHO .NET 4.0 VÀ NHIỀU KHUNG HÌNH GẦN ĐÂY

Đây là một câu hỏi cũ được đặt ra vào thời .Net 2.0, khi hỗ trợ cho các DLL ở chế độ hỗn hợp có vấn đề khởi tạo nghiêm trọng, dễ xảy ra tình trạng tắc nghẽn ngẫu nhiên. Kể từ .Net 4.0, việc khởi tạo các tệp DLL ở chế độ hỗn hợp đã thay đổi. Bây giờ có hai giai đoạn khởi tạo riêng biệt:

  1. Khởi tạo gốc, được gọi tại điểm vào của DLL, bao gồm thiết lập thời gian chạy C ++ gốc và thực thi phương thức DllMain của bạn.
  2. Khởi tạo được quản lý, được thực thi tự động bởi trình tải hệ thống.

Vì bước # 2 được thực hiện bên ngoài Khóa bộ tải nên không có bế tắc. Các chi tiết được mô tả tại Khởi tạo các lắp ráp hỗn hợp .

Để đảm bảo lắp ráp chế độ hỗn hợp của bạn có thể được tải từ một tệp thực thi gốc, điều duy nhất bạn cần kiểm tra là phương thức DllMain có được khai báo là mã gốc hay không. #pragma unmanagedcó thể giúp ở đây:

#pragma unmanaged

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

Điều quan trọng nữa là bất kỳ mã nào mà DllMain có thể gọi trực tiếp hoặc gián tiếp cũng không được quản lý. Bạn nên giới hạn loại chức năng được sử dụng bởi DllMain để bạn theo dõi tất cả mã có thể truy cập từ DllMain và đảm bảo rằng tất cả mã đều được biên dịch với#pragma unmanaged .

Trình biên dịch giúp bạn một chút bằng cách cung cấp cho bạn C4747 nếu nó phát hiện ra rằng DllMain không được khai báo là không được quản lý:

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

Tuy nhiên, trình biên dịch sẽ không tạo ra bất kỳ cảnh báo nào nếu DllMain gián tiếp gọi một số chức năng được quản lý khác, vì vậy bạn cần đảm bảo điều đó không bao giờ xảy ra, nếu không ứng dụng của bạn có thể bị deadlock ngẫu nhiên.


6

Nhấn ctr d + e Sau đó sử dụng nút hỗ trợ gỡ lỗi được quản lý. Sau đó, bỏ chọn LoaderLock.

Hy vọng điều này sẽ giúp bạn.


Phím tắt là alt + d + x
Narayan

3
Phím tắt thực sự phụ thuộc vào cấu hình bạn đã chỉ định để sử dụng trong lần chạy đầu tiên. Bố cục phím tắt C # là (Ctrl + D, E). (Ngoài ra, bạn có thể gán bất kỳ tổ hợp phím nào cho chức năng này trong Tùy chọn-> Môi trường-> Bàn phím.)
Adam LS

5

vui lòng nhắc những người dùng VS2017 đó rằng bạn cần phải tắt "trình trợ giúp ngoại lệ " thay vì " trợ lý ngoại lệ " (trước VS2017) để tránh lỗi khóa trình tải, đường dẫn thiết lập là Gỡ lỗi- > Ngoại lệ . Chỉ cần chạy int cho vấn đề này và lãng phí 2 giờ tìm kiếm giải pháp ...


Tôi không có "Ngoại lệ" trong "Gỡ lỗi". Tôi có Cộng đồng VS2017 15.8.4
Alex.

@ Alex, kiểm tra cho Debug -> Windows -> Cài đặt ngoại lệ, hoặc nhấn tổ hợp phím Ctrl + Alt + E
mistika

4

Gần đây tôi đã gặp lỗi này khi tạo một phiên bản COM-Object được viết bằng mã gốc:

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

Điều này dẫn đến lỗi được mô tả. Đã phát hiện thấy "LoaderLock" -Exception được ném.

Tôi đã khắc phục lỗi này bằng cách tạo đối tượng-instance trong một chuỗi bổ sung:

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

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

Lỗi có thể xảy ra với các đối tượng Có thể điều khiển (MarshalByRefObject) và giải pháp này không hoạt động với những đối tượng đó.
Matthieu

3

Tôi đang xây dựng C ++ CLR DLL (MSVS2015) phải thực hiện các cuộc gọi vào một DLL không được quản lý và xác định mã không được quản lý. Tôi sử dụng #pragma được quản lý và #pragma không được quản lý để kiểm soát chế độ của nó đối với một vùng mã nhất định.

Trong trường hợp của tôi, tôi chỉ cần đặt #pragma không được quản lý trước DllMain () và điều này đã giải quyết được vấn đề. Có vẻ như tôi đang nghĩ rằng tôi muốn một phiên bản được quản lý của DllMain ().



2

Đường dẫn cài đặt trong phiên bản visual studio 2017 của tôi là Gỡ lỗi -> Windows -> Cài đặt ngoại lệ. "Cửa sổ" cài đặt ngoại lệ hiển thị trong nhóm tab dưới cùng (trái ngược với một cửa sổ riêng biệt), tôi đã mất một lúc để nhận thấy nó. Tìm kiếm "bộ nạp".

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.