이 오류가 발생하여 여기서 무슨 일이 발생하는지 잘 모르겠습니다. 코드 스 니펫이 내 주장을 충분히하기를 바랍니다.
서버에 대한 응답에 내 데이터를 주입하기 위해 콜백을 수정하고 있습니다.
기본적으로 호출 스택은 다음과 같습니다.
mainRoutine(browseFunction(browseInternal), myBrowseFunction))
^ takes response ^ sends response ^ catches and modifies response
and sends callback
그래서 무슨 일이 일어나는가 : 나는 서버와 읽을 수있는 수백 개의 정적 노드를 가지고있다. 이제 저는 매우 동적 인 메시징 시스템을 지원하고 싶습니다. 노드를 생성하는 데는 300kb가 걸리므로 수만 개이고 몇 초 내에 생성 및 삭제되므로 옵션이 아닙니다. 따라서 응답에 메시지를 삽입하고 노드를 읽은 척합니다.
이론을 위해 너무 많이. 이 시스템은 이미 다른 상황에서 작동했기 때문에 서버가 가짜 응답을 처리 할 수 있다는 데 의심의 여지가 없습니다.
일부 코드-C ++로 작성되었지만 C의 serverstack에는 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 ()으로 돌아 가지 않고 첫 번째 기회와 처리되지 않은 예외로 충돌합니다.
demoserver.exe의 0x5f95ed6a에서 처리되지 않은 예외 : 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가 예상대로 작동하지 않고 여러 콜백을 마샬링한다는 사실이었습니다. 그것을 appeding하여 내 추가를 시도하면 충돌이 발생하여 예외가 발생했습니다. (솔루션과 구조는 여기에 게시하기에는 너무 복잡합니다.)
시간 내 주셔서 감사합니다. 어차피 힌트를 드리며 오류를 쫓으면서 많은 것을 배웠습니다!
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다