Greek Varak Ответов: 0

[C#] необработанное исключение типа "system.accessviolationexception" произошло в "xxxxx.dll"


У меня есть код c#, который вызывает dll (cpp build) и записывает текстовый файл (размером 12 МБ) txt-файла в переменную, вызывая cpp dll

Получение следующих ошибок :

{"Попытка чтения или записи защищенной памяти. Это часто указывает на то, что другая память повреждена."}

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.


Что я уже пробовал:

c# code :
// this is the code to call the dll (cpp build)

<pre> private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                System.Threading.ThreadStart starter = delegate { CallTheNumerOfTimesEx(1, 98600, "Thread1"); }; // 100000 95600
                System.Threading.Thread thread = new System.Threading.Thread(starter);
                thread.Start();

                thread.Join();

                string outputFile = @"D:\SampleJFile.txt";
                if (File.Exists(outputFile))
                    File.Delete(outputFile);
                string loging = someVariable // someVariable contains string size of 10 MB//

                using (StreamWriter writer = new StreamWriter(outputFile))
                    writer.WriteLine(toLog);
                obj.Information("Asdf", loging , "asdf"); // This is the (cpp build) dll function

            }
            catch (Exception ex)
            {
                tracelog.Error(ex);
            }
            MessageBox.Show("");

        }


cpp-функция, записывающая полученные данные :


void Trace::Information (String^ category, String^ messageText, String ^stackTrace)
{
    String ^oldCategory = traceMessage->category;
    TM->eventType = KTEventType::Information;
    TM->category = category;
    TM->errorCode = 0;
    TM->messageText = messageText;
    this->TM->timeStamp = DateTime::Now.ToString ("yyyy-MM-dd HH:mm:ss.fff");

    if (stackTrace == nullptr)
    {
        System::Diagnostics::StackTrace ^st = gcnew System::Diagnostics::StackTrace ();
        TM->stackTrace = st->ToString ();
    }
    else 
        TM->stackTrace = stackTrace;

    LogMessage (TM);
    TM->stackTrace = nullptr;
    TM->category = oldCategory;
};





данные переменные объявляются следующим образом

private:
     TraceMessage ^TM;

struct EXPORT_CLASS TraceMessage		
			{
public:
KTEventType	eventType;		
LPCWSTR		category;			
KTWSTRING		timeStamp;			
LPCWSTR		machineName;		
LPCWSTR		applicationName;	
LPCWSTR		userName;			
LPCWSTR		threadID;			
long		errorCode;			
LPCWSTR		messageText;		
LPCWSTR		stackTrace;			
LPCWSTR		errorSource;		
byte		logLevel;
}

void GenericLogger::LogMessage(ILogMessage^ logMessage)
{
	bool sharedMemoryLockHeld = false;
	try
	{	
		// Perform necessary validations
		// Validate the custom log message passed
		if(logMessage == nullptr)
		{
			throw gcnew ArgumentException("Custom log message passed to LogMessage method is null.");
		}
		
		// Validate the message id returned by the custom log message
		long messageId = logMessage->MessageId;
		
		// Ensure that the message id specified is non-negative
		if(messageId < 0)
		{
			throw gcnew ApplicationException("All custom message Ids must be positive integers. Please specify another message id for this custom log message.");
		}

		// Ensure that the message id specified is not a reserved message id
		// for TraceMessage message types
		if(messageId == 0)
		{
			throw gcnew ApplicationException("The message id '0' is reserved for TraceMessage message types. Please specify another message id for this custom log message.");
		}

		// Initialize the shared memory writer
		Init();
		
		// Use the BinaryFormatter to serialize the custom message
		// to the memory stream
		MemoryStream^ pMemStream = gcnew MemoryStream();
		BinaryFormatter^ pFormatter = gcnew BinaryFormatter();
		pFormatter->Serialize(pMemStream, logMessage);

		// Get the serialized byte array from the memory stream
		array<unsigned char>^ arrSerializedBytes = 
							pMemStream->GetBuffer();
		
		if(arrSerializedBytes != nullptr)
		{
			// Get the length of the serialized byte array
			int customMessageLength =  arrSerializedBytes->Length;

			if(customMessageLength > 0)
			{
				// The total message size =  
				// [Field that stores the length of the message (4 bytes)] + 
				// [Field that stores the message type (Trace/Custom/UnmanagedCustom (4 bytes))] +
				// [Field that stores the message Id (4 bytes)] +
				// [ Actual length of the serialized custom message].
				int totalMessageSize = customMessageLength + 12;
				
				// Begin writing into the shared memory. This actually procures the 
				// necessary locks for writing into shared memory
				m_pShmWriter->BeginWrite(totalMessageSize);
				sharedMemoryLockHeld = true;

				// Write the message type indicating that it is a 
				// custom message
				m_pShmWriter->AddLong((long)LogType::Custom);
				
				// Write the message id associated with the message
				m_pShmWriter->AddLong(messageId);

				// Write the serialized byte array to the shared memory
				m_pShmWriter->Write((array<system::byte> ^)arrSerializedBytes);
			}
		}
		
	}// end try
	catch(Exception^ pEx)
	{
		// Rethrow the exception
		Trace::WriteLine(pEx->Message);
		
	}
	finally
	{
		if(sharedMemoryLockHeld)
		{
			//Release all acquired locks in shared memory.
			m_pShmWriter->EndWrite();
			sharedMemoryLockHeld = false;
		}
	}



Может ли кто-нибудь предложить исправить эту проблему

Jochen Arndt

Из ваших фрагментов кода неясно, где происходит нарушение доступа, а также когда и как вызываются функции (например, что делает LogMessage ()?).

Большинство членов структуры TraceMessage являются указателями (LPCWSTR). Они будут действительны только в том случае, если назначенные объекты существуют и, следовательно, являются возможным источником вашей проблемы. Если это так, то они должны быть изменены на строковые объекты.

Greek Varak

Спасибо за ваш ответ яаар... я новичок в C++... На самом деле он ломается при
об..Информация("Asdf", loging , "asdf"); с ошибкой нарушения доступа.
он отлично работает, когда у нас есть samplejfile размером 9,99 Мб . Когда мы передаем 10 МБ текстового файла в библиотеку dll cpp, он терпит неудачу... Я попробую со строковыми объектами ... а сообщение журнала-это универсальная функция.

Jochen Arndt

параметр obj.Информация("впрыска", логин , "впрыска"); с нарушение прав доступа ошибка.

Начни с этого. Какова ценность "логинга"? Это параметр obj' действует? Проверьте код информационной функции и доступ к "loging".

Пожалуйста, не размещайте такие блоки кода в качестве комментариев. Они почти не читаются. Вы можете использовать зеленую ссылку "улучшить вопрос", чтобы добавить ее к вашему вопросу. Но публикуйте только код, связанный с этим вопросом (длинные вопросы также трудно читать, и многие, кто может помочь, пропустят их).

Greek Varak

Извини, Йохен, я сделал так, чтобы это был хороший вопрос, как ты и сказал ... На самом деле, когда я пытаюсь дебютировать через obj.information, нажав функцию F11, не отлаживается через dll... Вот тут я и ударил ....

Jochen Arndt

Без проблем.

Но это все еще неясно:

KTTrace::LogMessage(TraceMessage ^TM)

Что не соответствует

GenericLogger::LogMessage(ILogMessage^ logMessage)

Richard MacCutchan

Вам нужно использовать отладчик, чтобы проследить код и точно найти, где происходит исключение. Это должно помочь изолировать переменную, которая имеет плохой адрес.

0 Ответов