버그 해결을 위한 모든 질문을 던져
0 votes
255 views
안녕하세요. 게임 서버가 죽었는데 원인을 찾아야 하는데 찾기가 힘드네요.

게임 서버가 죽어서 미니 덤프 확인을 해 보니.. malloc 안에서 죽어버렸습니다.

죽었는 당시에 메모리 확인을 해 봤는데 메모리는 충분 했습니다.

 

1. 여기서 _heap_alloc에 실패를 하고 _callnewh함수를 타는데요

void * __cdecl _malloc_base (size_t size)
{
    void *res = NULL;

    //  validate size
    if (size <= _HEAP_MAXREQ) {
        for (;;) {

            //  allocate memory block
            res = _heap_alloc(size);

            //  if successful allocation, return pointer to memory
            //  if new handling turned off altogether, return NULL

            if (res != NULL)
            {
                break;
            }
            if (_newmode == 0)
            {
                errno = ENOMEM;
                break;
            }

            //  call installed new handler
            if (!_callnewh(size))
                break;

            //  new handler was successful -- try to allocate again
        }
    } else {
        _callnewh(size);
        errno = ENOMEM;
        return NULL;
    }

 

2.  pnhHeap이 NULL 값 입니다. 왜 NULL인지 모르겠네요 그래서 죽는거 같습니다.

extern "C" int __cdecl _callnewh(size_t size)
{
        {
            _PNH pnh = (_PNH) _decode_pointer(_pnhHeap);

            if ( (pnh == NULL) || ((*pnh)(size) == 0) )
                return 0;
        }
        return 1;
}

 

////////////////////////

어셈블리 코드

extern "C" int __cdecl _callnewh(size_t size)
{
        {
            _PNH pnh = (_PNH) _decode_pointer(_pnhHeap);
00530019 FF 35 BC 75 60 00 push        dword ptr [_pnhHeap (6075BCh)]
0053001F E8 D1 05 00 00   call        _decode_pointer (5305F5h)

            if ( (pnh == NULL) || ((*pnh)(size) == 0) )
00530024 85 C0            test        eax,eax
00530026 59               pop         ecx  
00530027 74 0F            je          _callnewh+1Fh (530038h)
00530029 FF 74 24 04      push        dword ptr [esp+4]
0053002D FF D0            call        eax  
0053002F 85 C0            test        eax,eax             <------- 이쪽을 가리키고 있음
00530031 59               pop         ecx  
00530032 74 04            je          _callnewh+1Fh (530038h)

 

 

이런 문제는 어떻게 답을 찾아야 할까요? 로그를 찾아봐도 도움 될만한 것들이 없습니다.
asked (2 point) , 255 views
minidump xml 확인을 해 보니

 

<ExceptionType>4</ExceptionType>

 

설명서를 보니..

4 : C++ new operator fault.

이렇게 뜨네요.. 도대체 어떤 상황에서 이런 메세지가 뜨는지 모르겠네요 Size는 65592 사이즈 만큼 할당 시도하려고 했고 메모리도 충분히 있었는데..
1. 메모리 단편화로 인해 한번에 65592 크기의 메모리를 할당할 수 없는 경우.
2. 32bit 빌드인 상태에서 힙 메모리 2기가 이상을 사용하려고 한 경우 (시스템 전체 여유 메모리와 상관 없이).

정도로 예상됩니다....만

 

뻗기 전의 프로세스 메모리 사용량을 확인해봐야 할 것 같습니다
1번에 해당하는걸로 예상합니다.

 

2번은 죽기전 해당 프로세스 메모리 사용량이 300M정도 사용하고 있었습니다.

 

답변 감사합니다.

1 답변

0 votes
메모리 단편화 문제가 아닌가 싶습니다.

게임 서버라면 실시간 메모리 할당은 자제하는 게 좋습니다.

설계 용량을 정하시고(동접 얼마..) 설계에 맞게 예측이 가능한 (큰) 메모리는 미리 할당해서 계속 재활용해서 쓰고요.

어쩔 수 없이 할당해야 하는 자잘한 메모리는..

작은 메모리 전용 커스텀 메모리 매니저를 만들어서 사용하는 게 좋을 거 같습니다.

일정 크기(예: 128) 이하의 메모리가 필요하면,

이미 확보된 고정 사이즈 메모리 블록 Pool에서 가져다 쓰는 방식이죠.

실시간 힙 할당은 아예 없는 게 가장 좋습니다.
answered (285 point)
윈도우 서버라면 C 런타임 에서 제공하는 메모리 함수만으로도 Low-Fragmentation-Heap 이 가능해서 단편화 걱정은 크게 안해도 될 것 같습니다.

버그 해결을 위해 도움을 구하고, 도움을 주세요. 우리는 그렇게 발전합니다.

throw bug 는 프로그래밍에 대한 전분야를 다룹니다. 질문,논의거리,팁,정보공유 모든 것이 가능합니다. 프로그래밍과 관련이 없는 내용은 환영받지 못합니다.

110 질문
204 answers
219 댓글
230 users