malloc/free/new/delete에서 컴파일러가 메모리를 0xCD, 0xDD 등으로 초기화하는 시기와 이유는 무엇입니까?
나는 컴파일러 가끔 컴파일러는 다음과 같은 특정 패턴으로 메모리를 초기화할 수 있습니다 같은 패턴 기억과 함께 초기화하게 될 것이다.0xCD
그리고 그리고.0xDD
내가 알고 싶은 것은 언제, 왜 이런 일이 일어나느냐는 것이다.
언제
이것은 사용하는 컴파일러에 고유한 것입니까?
도 마라malloc/new
그리고 그리고.free/delete
은 같은 방법으로 이와 관련하여 일합니까?이와 관련하여 동일한 방식으로 작동합니까?
플랫폼 고유의 것입니까?
그것 기타 운영체제(예와 같은 다른 운영 체제에 발생할 것이다.Linux
★★★★★★★★★★★★★★★★★」VxWorks
왜죠
내가 알기로는 이것은제가 알기로는에서 발생한다다음에서만 발생합니다 오직 이것은.Win32
Debug 구성,고, 컴파일러 캐치 예외를 돕기 위해 메모리 초과를 검출하는데 사용합니다.메모리 오버런을 검출하고 컴파일러가 예외를 검출하는 데 사용됩니다.
이 초기화가 어떻게 유용한지에 대한 실용적인 예를 들어주시겠습니까?
나는 무언가를 읽고(혹시 코드 Complete2) 때 할당하고 알려진 패턴 메모리를 초기화하고 패턴 메모리를에 인터럽트로 번질 것이라고 좋다 할당할 때 이미 알고 있는 패턴으로 초기화하는 것이 좋고, 특정 패턴은 인터럽트를 트리거한다는 것을 코드 컴플리트2에서 읽은 것을 기억합니다 말한 기억이 난다.Win32
어떤 예외가 디버거에서 보여 주고 이어질 것이다.그러면디버거에 예외가 표시됩니다.
얼마나 휴대할 수 있습니까?
Microsoft 컴파일러가 디버깅모드로 컴파일 했을 때, 미소유/미초기화 메모리의 다양한 비트에 사용하는 기능의 간단한 개요(컴파일러 버전에 따라 다를 수 있습니다).
Value Name Description
------ -------- -------------------------
0xCD Clean Memory Allocated memory via malloc or new but never
written by the application.
0xDD Dead Memory Memory that has been released with delete or free.
It is used to detect writing through dangling pointers.
0xED or Aligned Fence 'No man's land' for aligned allocations. Using a
0xBD different value here than 0xFD allows the runtime
to detect not only writing outside the allocation,
but to also identify mixing alignment-specific
allocation/deallocation routines with the regular
ones.
0xFD Fence Memory Also known as "no mans land." This is used to wrap
the allocated memory (surrounding it with a fence)
and is used to detect indexing arrays out of
bounds or other accesses (especially writes) past
the end (or start) of an allocated block.
0xFD or Buffer slack Used to fill slack space in some memory buffers
0xFE (unused parts of `std::string` or the user buffer
passed to `fread()`). 0xFD is used in VS 2005 (maybe
some prior versions, too), 0xFE is used in VS 2008
and later.
0xCC When the code is compiled with the /GZ option,
uninitialized variables are automatically assigned
to this value (at byte level).
// the following magic values are done by the OS, not the C runtime:
0xAB (Allocated Block?) Memory allocated by LocalAlloc().
0xBAADF00D Bad Food Memory allocated by LocalAlloc() with LMEM_FIXED,but
not yet written to.
0xFEEEFEEE OS fill heap memory, which was marked for usage,
but wasn't allocated by HeapAlloc() or LocalAlloc().
Or that memory just has been freed by HeapFree().
면책사항: 표는 제가 가지고 있는 메모에서 가져온 것입니다. 100% 정확하지 않을 수 있습니다(또는 일관성이 있을 수 있습니다.
이러한 값의 대부분은 vc/crt/src/dbgheap.c에 정의되어 있습니다.
/*
* The following values are non-zero, constant, odd, large, and atypical
* Non-zero values help find bugs assuming zero filled data.
* Constant values are good, so that memory filling is deterministic
* (to help make bugs reproducible). Of course, it is bad if
* the constant filling of weird values masks a bug.
* Mathematically odd numbers are good for finding bugs assuming a cleared
* lower bit.
* Large numbers (byte values at least) are less typical and are good
* at finding bad addresses.
* Atypical values (i.e. not too often) are good since they typically
* cause early detection in code.
* For the case of no man's land and free blocks, if you store to any
* of these locations, the memory integrity checker will detect it.
*
* _bAlignLandFill has been changed from 0xBD to 0xED, to ensure that
* 4 bytes of that (0xEDEDEDED) would give an inaccessible address under 3gb.
*/
static unsigned char _bNoMansLandFill = 0xFD; /* fill no-man's land with this */
static unsigned char _bAlignLandFill = 0xED; /* fill no-man's land for aligned routines */
static unsigned char _bDeadLandFill = 0xDD; /* fill free objects with this */
static unsigned char _bCleanLandFill = 0xCD; /* fill new objects with this */
또한 그곳엔 그 디버그 런타임을 채울 예정이다 버퍼가 알려진 값과(또는 부품의 버퍼)몇번이나 예를 들어, 또한의 'slack의 우주 디버깅 실행 시 버퍼(또는 버퍼의 일부)를 기존의 값으로 채우는 경우도 있습니다 있다.예를 들어,의 '슬랙의공간은std::string
가 " "로 fread()
합니다._SECURECRT_FILL_BUFFER_PATTERN
:crtdefs.h
언제 도입되었는지는 정확히 알 수 없지만 적어도 VS 2005(VC++8)에 의해 디버깅 실행 중이었습니다.
위해 은 "Digital" 입니다.0xFD
되는 것과 값. - 무인의 땅에 사용되는 값. - 무인의 땅에 사용되는 값. 2008 2008(VC++9)으로 되었습니다.0xFE
큰 을 지나 조작이 될 수 있기 fread()
값 " " " "는 " " 입니다0xFD
버퍼 크기가 1개만 너무 크면 채우기 값이 카나리아 초기화에 사용된 노맨의 토지 값과 같기 때문에 오버런 검출을 트리거하지 않을 수 있습니다.어떤 사람의 땅에도 변화가 없다는 것은 과잉현상을 눈치채지 못한다는 것을 의미한다.
따라서 VS 2008에서 채우기 값이 변경되어 이러한 경우 노맨 랜드 카나리아가 변경되어 런타임에 의해 문제를 검출할 수 있게 되었습니다.
다른 사람이 지적한 바와 같이 이들 값의 주요 속성 중 하나는 이들 값 중 하나를 가진 포인터 변수가 참조 해제되면 액세스 위반이 발생한다는 것입니다.표준 32비트 Windows 구성에서는 사용자 모드주소가 0x7ffff보다 높지 않기 때문입니다.
채우기 값 0xCCCCC의 좋은 속성 중 하나는 x86 어셈블리에서 opcode 0xCC는 int3 opcode로 소프트웨어 브레이크포인트 인터럽트라는 것입니다.따라서, 만약 당신이 그 가득찬 값을 채운 초기화되지 않은 메모리에서 코드를 실행하려고 한다면, 당신은 즉시 중단점에 도달하게 될 것이고, 운영체제는 당신이 디버거를 연결하거나 프로세스를 종료하게 할 것이다.
Studio는 이 operating system으로 되어 있는지 할 수 .malloc
memory,되지 않은 객체.ed, ed, ed, ed, ed, ed, ed, ed, ed, ed, , object.
https://docs.microsoft.com/en-gb/visualstudio/debugger/crt-debug-heap-details?view=vs-2022
이것은 사용하는 컴파일러에 고유한 것입니까?
사실, 이것은 거의 항상 런타임 라이브러리의 기능입니다(C 런타임 라이브러리 등).런타임은 보통 컴파일러와 강하게 관련되어 있지만 스왑할 수 있는 조합이 있습니다.
Windows 에서는 디버깅히프(HeapAlloc 등)도 디버깅C 런타임 라이브러리의 malloc 및 무료 구현과는 다른 특수한 채우기 패턴을 사용합니다.OS의 기능일 수도 있지만 대부분의 경우 언어 런타임 라이브러리일 뿐입니다.
malloc/new와 free/delete는 같은 방식으로 동작합니까?
new와 delete의 메모리 관리 부분은 보통 malloc 및 free로 구현되기 때문에 new와 delete로 할당된 메모리의 기능은 동일합니다.
플랫폼 고유의 것입니까?
을 사용하다실제 사용되는 값은 16진수 덤프를 볼 때 특이하고 명백하게 보일 뿐만 아니라 프로세서의 기능을 활용할 수 있는 특정 속성을 갖도록 설계되어 있습니다.예를 들어, 홀수 값은 선형 결함을 유발할 수 있기 때문에 종종 사용됩니다.초기화되지 않은 카운터에 루프하면 예기치 않은 지연이 발생하기 때문에 큰 값이 사용됩니다(0이 아니라).는 x86 ( 0xCC )입니다.int 3
초기화되지 않은 메모리를 실행하면 트랩이 됩니다.
Linux 또는 VxWorks와 같은 다른 운영 체제에서 이 문제가 발생합니까?
대부분의 경우 사용하는 런타임 라이브러리에 따라 달라집니다.
이 초기화가 어떻게 유용한지에 대한 실용적인 예를 들어주시겠습니까?
위에 몇 가지 나열했습니다.이 값은 일반적으로 메모리 중 유효하지 않은 부분(긴 지연, 트랩, 얼라인먼트 장애 등)으로 작업을 했을 때 비정상적인 일이 발생할 가능성을 높이기 위해 선택됩니다.힙 관리자는 할당 간의 간격에 특수 채우기 값을 사용하는 경우도 있습니다.이러한 패턴이 변경되면 어딘가에 잘못된 쓰기(버퍼 오버런 등)가 있음을 알 수 있습니다.
메모리를 할당할 때 이미 알려진 패턴으로 초기화하는 것이 좋다는 것을 (아마도 코드 컴플리트 2에서) 읽은 것을 기억합니다.또한 특정 패턴은 Win32에서 인터럽트를 트리거하여 디버거에 예외가 표시되도록 합니다.
얼마나 휴대할 수 있습니까?
솔리드 코드 작성(및 코드 완성)에서는 채우기 패턴을 선택할 때 고려해야 할 사항에 대해 설명합니다.여기서 몇 가지 언급을 했습니다만, 매직 넘버(프로그래밍)에 관한 Wikipedia 기사에도 정리되어 있습니다.사용하시는 프로세서의 사양에 따라서는, 몇개의 트릭이 다릅니다(예를 들면, 읽기와 쓰기의 정렬이 필요한지 어떤지, 또, 트랩 하는 명령에 매핑 되는 값이 무엇인지 등).메모리 덤프에서 눈에 띄는 큰 값이나 비정상적인 값을 사용하는 등의 다른 트릭은 보다 휴대성이 뛰어납니다.
OS가 아니라 컴파일러입니다.동작도 수정할 수 있습니다.이 투고의 하단을 참조해 주세요.
Microsoft Visual Studio는 스택메모리를 0xCC로 프리필하는 바이너리를 (디버깅모드로) 생성합니다.또한 버퍼 오버플로우를 검출하기 위해 각 스택프레임 사이에 공간을 삽입합니다.이것이 도움이 되는 매우 간단한 예는 다음과 같습니다(실제로 Visual Studio는 이 문제를 발견하고 경고를 보냅니다).
...
bool error; // uninitialised value
if(something)
{
error = true;
}
return error;
Visual Studio에서 변수를 알려진 값으로 미리 초기화하지 않은 경우 이 버그를 찾기 어려울 수 있습니다.사전 초기화 변수(또는 사전 초기화 스택 메모리)를 사용하면 모든 실행에서 문제가 재현됩니다.
다만, 약간의 문제가 있습니다.Visual Studio에서 사용하는 값은 TRUE입니다. 0을 제외한 모든 값은 TRUE입니다.실제로 릴리스 모드에서 코드를 실행하면 유니터리화 변수가 0을 포함하는 스택메모리에 할당될 수 있습니다.즉, 유니터리화 변수 버그가 발생할 수 있습니다.이 버그는 릴리스 모드에서만 나타납니다.
그래서 저는 이 바이너리를 직접 편집하여 프리필 값을 수정하는 스크립트를 작성했습니다.이 스크립트를 사용하면 스택에 0이 포함되어 있을 때만 나타나는 비초기화 변수 문제를 찾을 수 있습니다.이 스크립트는 스택의 프리필을 변경할 뿐입니다.히프 프리필을 실험해 본 적은 없지만 가능합니다.런타임 DLL 편집이 필요할 수도 있고 그렇지 않을 수도 있습니다.
이 문서에서는 비정상적인 메모리비트 패턴 및 이러한 값이 발생했을 때 사용할 수 있는 다양한 기술에 대해 설명합니다.
그 이유는 다음과 같은 클래스가 있다고 가정하기 때문입니다.
class Foo
{
public:
void SomeFunction()
{
cout << _obj->value << endl;
}
private:
SomeObject *_obj;
}
한 한다.Foo
를 호출합니다.SomeFunction
「」를합니다.0xCDCDCDCD
이것은, 무엇인가를 초기화하는 것을 잊은 것을 의미합니다.그게 바로 '왜' 부분이죠.그렇지 않으면 포인터가 다른 메모리와 정렬되어 디버깅이 더 어려워질 수 있습니다.액세스 위반이 발생하는 이유를 알려 주는 것입니다.이 경우는 매우 간단하지만, 규모가 큰 클래스에서는 실수를 저지르기 쉽습니다.
AFAIK, 이것은 디버깅모드(릴리즈가 아닌)일 때만 Visual Studio 컴파일러에서 동작합니다.
프로세스가 실행 중일 때 디버거를 연결할 수 있기 때문에 일반적으로 디버깅 중에 메모리가 초기 시작 값에서 변경되었음을 쉽게 확인할 수 있습니다.
메모리뿐만 아니라 많은 디버거가 프로세스가 시작될 때 레지스터 내용을 sentinel 값으로 설정합니다(AIX의 일부 버전은 일부 레지스터를 다음과 같이 설정합니다).0xdeadbeef
이치노
IBM XLC 컴파일러에는 사용자가 지정한 값을 자동 변수에 할당하는 "initauto" 옵션이 있습니다.디버깅 빌드에 다음 항목을 사용했습니다.
-Wc,'initauto(deadbeef,word)'
초기화되지 않은 변수의 저장소를 보면 0xdeadbeef로 설정됩니다.
언급URL : https://stackoverflow.com/questions/370195/when-and-why-will-a-compiler-initialise-memory-to-0xcd-0xdd-etc-on-malloc-fre
'programing' 카테고리의 다른 글
vue.js 템플릿 내의 php 어레이에 액세스합니다. (0) | 2022.08.18 |
---|---|
Java에서 바이트 배열을 정수로 변환하거나 그 반대로 변환합니다. (0) | 2022.08.18 |
[Vue warn] :속성 또는 메서드가 인스턴스에서 정의되지 않았지만 렌더링 중에 참조됩니다. (0) | 2022.08.18 |
인수가 있는 Vuex 매핑 Getter - 캐시됨? (0) | 2022.08.18 |
C에서 함수를 매개 변수로 전달하려면 어떻게 해야 합니까? (0) | 2022.08.18 |