Я столкнулся с этой ошибкой, и я не совсем понимаю, что здесь происходит.
Я надеюсь, что codenippet достаточно, чтобы сделать мою точку зрения.
Я модифицирую функцию обратного вызова, чтобы ввести свои собственные данные в ответ на сервер.
По сути, стек вызовов выглядит следующим образом:
mainRoutine(browseFunction(browseInternal), myBrowseFunction))
^ takes response ^ sends response ^ catches and modifies response
and sends callback
Итак, что происходит:
У меня есть сервер и несколько сотен статических узлов для чтения. Теперь я хочу поддержать высокодинамичную систему обмена сообщениями, создание узла занимает 300 КБ, поэтому это не вариант, так как их десять тысяч, которые создаются и удаляются в течение нескольких секунд. Поэтому я вставляю сообщение в ответ и делаю вид, что узел прочитан.
Так много для теории. Эта система уже работала в другом контексте, поэтому нет сомнений, что сервер может обработать поддельный ответ …
Некоторый код написан на c ++, но с серверным стеком в C нет доступных методов new () или delete (). Все переменные инициализируются и заполняются разумными значениями, насколько это возможно.
volatile int pNoOfNodesToAppend = 5;
Boolean xAdapter::Browse(BaseNode *pNode, BrowseContext* pBrowseCtx, int i)
{
[... some initializations....]
BrowseResult* pBrowseResult = &pResponse->Results[i];
int NoOfReferences = pBrowseResult->NoOfReferences + pNoOfNodesToAppend;
pResponse->NoOfResults = NoOfReferences;
// Version one
ReferenceDescription* refDesc = reinterpret_cast <ReferenceDescription *>(realloc(
pBrowseResult->References,
sizeof(OpcUa_ReferenceDescription) * NoOfReferences));//Version two I tried just out of curiousity to see whether copying "by hand" would cause the programm to crash, as it didn't allocate enough memory - but no problem there.
/*
ReferenceDescription* refDesc = reinterpret_cast <ReferenceDescription *>(malloc( NoOfReferences * sizeof(ReferenceDescription)));
for (int k = 0; k < NoOfReferences; k++)
{
memcpy(&pBrowseResult->References[0], &pBrowseResult->References[k], sizeof(ReferenceDescription));
}
*/int size = _msize(refDesc);
pBrowseResult->NoOfReferences = NoOfReferences;
if (refDesc != NULL)
{
pBrowseResult->References = refDesc;
}
else
{
return False;
/* Errorhandling ... */
}[Fill with data... check for errors, handle errors]
return True;
}
Я знаю, что этот код выглядит громоздким, но большая часть его не может быть выполнена проще из-за лежащего в основе стека, так как он дает мне сложность приведения типов вперед и назад, содержащих множество структур.
Этот код компилируется и работает нормально, после отправки обратного вызова происходит сбой с нарушением прав доступа в ABABABAB, который, как я выяснил, является магическое число, используемое отладкой Microsoft для маркировки защитных битов вокруг памяти heapAlloc () (4 бита до и после).
Смотрите здесь: Magic_debug_values 1
Редактировать: Этот раздел решен. Я был слишком слеп, чтобы понять, что мы говорим здесь о HEX, и поэтому слишком глуп, чтобы правильно рассчитать мои цифры. Так что считайте это недостойным чтения за исключением понимания комментариев.
Что действительно вызывает у меня головную боль, так это размер выделенного нового массива.
NoOfReferences: 6
sizeof(ReferenceDescription) 0x00000080 unsigned int
(NoOfReferences * sizeof(ReferenceDescription)) 0x00000300 unsigned long
sizeof(*refDesc) 0x00000080 unsigned int //pointer to first element of array
_msize says:
size of (*refDesc) 0x00000300 int
Теперь, ПОЧЕМУ размер вновь выделенного пространства 300? Если мой разум не обманывает меня, то 6 * 80 равен 480, даже если там, где вокруг каждого элемента 8 защитных битов, он все равно будет 72 * 6> 300 бит. В любом случае система работает нормально.
Теперь в следующем фрагменте кода структуры в массиве заполнены полезными данными и переданы обратно Response
состав.
Обратный вызов отправлен, сервер не возвращается к ServerMain (), а затем падает с первым шансом и необработанным исключением
Необработанное исключение в 0x5f95ed6a в demoserver.exe: 0xC0000005:
Нарушение прав доступа по месту нахождения 0xabababab.
0x5F95ED6A f3 a5 ff 24 95 84 ee 95 5f 90 8b c7 ba 03 00 00 00 83 e9 04 72 ó¥ÿ$..î._..Ǻ....ƒé.r
0x5F95ED7F 0c 83 e0 03 03 c8 ff 24 85 98 ed 95 5f ff 24 8d 94 ee 95 5f 90 .ƒà..Èÿ$.˜í._ÿ$.”î._.
0x5F95ED94 ff 24 8d 18 ee 95 5f 90 a8 ed 95 5f d4 ed 95 5f f8 ed 95 5f 23 ÿ$..î._.¨í._Ôí._øí._#
0x5F95EDA9 d1 8a 06 88 07 8a 46 01 88 47 01 8a 46 02 c1 e9 02 88 47 02 83 ÑŠ.ˆ.ŠF.ˆG.ŠF.Áé.ˆG.ƒ
0x5F95EDBE c6 03 83 c7 03 83 f9 08 72 cc f3 a5 ff 24 95 84 ee 95 5f 8d 49 Æ.ƒÇ.ƒù.rÌó¥ÿ$..î._.I
0x5F95EDD3 00 23 d1 8a 06 88 07 8a 46 01 c1 e9 02 88 47 01 83 c6 02 83 c7 .#ÑŠ.ˆ.ŠF.Áé.ˆG.ƒÆ.ƒÇ
0x5F95EDE8 02 83 f9 08 72 a6 f3 a5 ff 24 95 84 ee 95 5f 90 23 d1 8a 06 88 .ƒù.r¦ó¥ÿ$..î._.#ÑŠ.ˆ
0x5F95EDFD 07 83 c6 01 c1 e9 02 83 c7 01 83 f9 08 72 88 f3 a5 ff 24 95 84 .ƒÆ.Áé.ƒÇ.ƒù.rˆó¥ÿ$..
0x5F95EE12 ee 95 5f 8d 49 00 7b ee 95 5f 68 ee 95 5f 60 ee 95 5f 58 ee 95 î._.I.{î._hî._`î._Xî.
0x5F95EE27 5f 50 ee 95 5f 48 ee 95 5f 40 ee 95 5f 38 ee 95 5f 8b 44 8e e4 _Pî._Hî._@î._8î._.DŽä
0x5F95EE3C 89 44 8f e4 8b 44 8e e8 89 44 8f e8 8b 44 8e ec 89 44 8f ec 8b .D.ä.DŽè.D.è.DŽì.D.ì.
0x5F95EE51 44 8e f0 89 44 8f f0 8b 44 8e f4 89 44 8f f4 8b 44 8e f8 89 44 DŽð.D.ð.DŽô.D.ô.DŽø.D
0x5F95EE66 8f f8 8b 44 8e fc 89 44 8f fc 8d 04 8d 00 00 00 00 03 f0 03 f8 .ø.DŽü.D.ü........ð.ø
0x5F95EE7B ff 24 95 84 ee 95 5f 8b ff 94 ee 95 5f 9c ee 95 5f a8 ee 95 5f ÿ$..î._.ÿ”î._œî._¨î._
0x5F95EE90 bc ee 95 5f 8b 45 08 5e 5f c9 c3 90 8a 06 88 07 8b 45 08 5e 5f .î._.E.^_ÉÃ.Š.ˆ..E.^_
0x5F95EEA5 c9 c3 90 8a 06 88 07 8a 46 01 88 47 01 8b 45 08 5e 5f c9 c3 8d ÉÃ.Š.ˆ.ŠF.ˆG..E.^_ÉÃ.
Так что ошибка была найдена. Проблема заключалась не в выделении или переназначении массива, а в том, что API не вел себя так, как ожидалось, и вывел несколько обратных вызовов. Попытка добавить мой путем добавления завершилась сбоем и вызвала исключение, так как это не было сделано таким образом. (Решение и структура будут слишком сложными, чтобы разместить их здесь.)
Спасибо за ваше время и подсказки в любом случае, я многому научился, преследуя ошибки!
Других решений пока нет …