fprintf stderr segfaults в своем собственном потоке, работает в основном - PullRequest
0 голосов
/ 30 января 2019

Я создал небольшую прототипную тестовую программу, которая работает со счетчиками производительности Windows, и все, кажется, работает нормально.Я переместил его в мою dll, которую загружает моя основная программа, и есть некоторые fprintf (stderr, "sometext"), которые вызывают нарушение прав доступа.

Я смотрю на это на SO и не нашел удовлетворительного ответа,Я знаю, что он работает нормально, когда он работает в основном потоке.Я предполагаю, что это из потока TIME_CRITICAL, который я порождаю, для опроса счетчика производительности.

  1. В чем причина этого нарушения доступа?В нем говорится «необработанное исключение в 0x7deadbeef в main.exe 0xC00000005. Чтение нарушения доступа из 0xFbeefdead».
  2. Каков подходящий способ печати на stderr из отдельного потока?

Кажется, это "случайный" тип, поскольку у меня есть printfs в начале функции опроса, котораяпечатать нормально.Внизу они бросают нарушение доступа.Почему некоторые printf / fprintf (stderr) работают нормально, в то время как другие терпят неудачу?

EDIT Я создаю поток с 0 в качестве параметра размера стека, который по умолчанию должен соответствовать размеру стека по умолчанию.Я подозреваю, что я выдуваю свой стек в этой теме, кто-нибудь знает это?https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createthread

1 Ответ

0 голосов
/ 31 января 2019

Как я и подозревал, проблема была связана с чем-то, не связанным с printf / fprintfs.На раннем этапе программы я спринтовал много строк, которые были частью структуры.Вместо того, чтобы передавать размер члена структуры в sprintf, я передал размер всей структуры, что привело к переполнению буфера и искажению бог знает, сколько памяти.Когда это было в одном главном потоке, оно не переполнялось достаточно, чтобы уничтожить мой стек и вызвать segfault, но оно все равно записывалось за пределы буфера.

Поскольку в автономной программе было меньше вызовов функций, вероятность перезаписи указателя стека была равна нулю, когда при вводе в реальную программу / dll иерархия вызовов становится нетривиальной, и происходит значительное переполнение буфера.Обязательно перезаписывайте указатель стека, поэтому printf из потока с диапазоном адресов 0x7ABCDEF пытается перейти к адресу возврата 0xF1234567, вызывая нарушение доступа.

Я разместил здесь свою историю для будущих читателей.Вот некоторый ресурс sprintf_s, если у следующего парня есть похожая проблема: Что такое sprintf_s аналог sprintf (newpath, "% s% s", ...)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...