디스어셈블리 디버깅 도중 어떻게 접근해야 할지 질문 드립니다.

ehaakdl의 이미지

ebp2751132 <- esp2750908
생성자 호출 되는시점 문법지점
011ABC50 push ebp 2751132
011ABC51 mov ebp,esp(2750908)
ebp = 2750904 잘못 복사됨 이지점 부터

unordered_map을 추가한 후 부터 클래스 선언만 해도 run time 에러로 스택 손상 떠서
unordered_map이 문제인가 해서 다른 클래스에 넣고 insert/find 해봤습니다. 문제 없이 잘되더군요.--..
그래서 이건 좀 더 깊게 들어가 봐야 알 수 있을거 같아서 디스어셈블리 코드 따라가 봤는데
명령어 mov ebp,esp 에서 기존 esp값이 복사되야 하는데 엉뚱한게 복사 됬습니다. 거기서 부터 잘못된
값이 복사 되서 결국은 _RTC_CheckStackVars 여깃 잡혀서 스택 오염으로 걸렸는데 도대체 왜 잘못된 값이 어디서 유입이 됬길래 그 위로는 아무것도 없는데 ...감이 안잡혀서 질문 드립니다.

class PreferencesMangement
{
	public:
	PreferencesMangement();
	~PreferencesMangement();
	bool InitPreferenceVal();
 
private:
	unordered_map<string, void*> mPreferenceVal;
	string  VerificationNetworkProferty(const char* pProfertyValue, const char* pProfertyName);
};

PreferencesMangement::PreferencesMangement()
{
 
}
 
PreferencesMangement::~PreferencesMangement()
{
	printf("dd");
}
 
bool PreferencesMangement::InitPreferenceVal()
{
	bool bResult = true;
	list<string> allFileName;
	allFileName.push_back(FILE_NAME_NETWORK);
	ifstream openFile;
	char readFileLine[MAX_READ_LINE_LENGTH] = { 0 };
	char* pSliceRes = nullptr;
	char* pAfterSlice =  nullptr;
	char delemiterProferty = DELIMITING;
	char readProfertyName[MAX_PROFERTY_LENGTH] = { 0 };
	string errorMsg;
	string someFileName;
	string someProfertyValue;
	list<string>::iterator allFileNameIter;
 
	for (allFileNameIter = allFileName.begin(); allFileNameIter != allFileName.end(); ++allFileNameIter)
	{
		someFileName.append(PROFERY_FULL_PATH);
		someFileName.append(*allFileNameIter);
		openFile.open(someFileName, ios::binary);
		if (openFile.fail()) 
		{
			return false;
		}
			while (!openFile.eof())
			{	
				openFile.getline(readFileLine, sizeof readFileLine);
				if (openFile.fail())
				{
					allFileName.clear();
					openFile.close();
					return false;
				}
				pSliceRes = strtok_s(readFileLine, &delemiterProferty, &pAfterSlice);
				if (pSliceRes && pAfterSlice)
				{
					strcpy_s(readProfertyName, sizeof(readProfertyName),pSliceRes);
					someFileName = VerificationNetworkProferty(pAfterSlice, readProfertyName);
					if (someFileName.compare(ERROR_MSG[1]))
					{
						allFileName.clear();
						openFile.close();
						return false;
					}
					someProfertyValue.copy(pAfterSlice, sizeof(char)* _MAX_DIR);
					//mPreferenceVal.insert(someFileName, someProfertyValue);
				}
				else
				{
					allFileName.clear();
					openFile.close();
					return false;
				}
				someProfertyValue.clear();
				pSliceRes = nullptr;
				pAfterSlice = nullptr;
				someFileName.clear();
				memset(readFileLine, 0, sizeof(readFileLine));
			}
		allFileName.clear();
		openFile.close();
	}
	return true;
}
익명 사용자의 이미지

push ebp
mov ebp,esp

실행 전에 ebp=2751132, esp=2750908이라면, 위 코드의 실행을 마친 후 ebp에는 2750904가 저장되는 것이 맞습니다.
push ebp가 esp를 4 감소시키기 때문이지요.

위 코드는 x86에서 흔히 보이는 함수 프롤로그인데, 이 정도도 제대로 실행하지 못할 정도로 CPU에 문제가 있다면 아마 부팅도 제대로 안 될 겁니다.

런타임 에러 원인은 어딘가 다른 데 있을 가능성이 높습니다.

익명 사용자의 이미지

위의 코드는 mPreferenceVal의 타입을 굳이 unordered_map<string, void*>로 해야 할 이유가 보이지 않는 코드입니다. unordered_map<string, string>으로 선언하면 본문의 문제는 깔끔하게 해결될 겁니다. 해결되는 이유는 차분히 생각해 보시면 알 수 있을 겁니다.

익명 사용자의 이미지

위의 코드는 mPreferenceVal의 타입을 굳이 unordered_map로 해야 할 이유가 보이지 않는 코드입니다. unordered_map으로 선언하면 본문의 문제는 깔끔하게 해결될 겁니다. 해결되는 이유는 차분히 생각해 보시면 알 수 있을 겁니다.
김정균의 이미지

텍스트 양식을 plain text 로 하시거나 &lt;, &gt; 로 작성해 주시면 됩니다. 원글은 제가 텍스트양식을 plain text 로 변경해 드렸습니다.

ehaakdl의 이미지

감사합니다.

익명 사용자의 이미지

원문 수정해 주셔서 감사합니다.

ehaakdl의 이미지

아 제가 c++ 배우는중이라 최근에 스마트 포인터 배웠습니다.. 고칠게요
아 그리고 문제는 해결 됬습니다. boost build 다시 하니까 되더라구여..
이상하게 build 했었나 봅니다. boost도 처음 써봐서
그래도 한번 디스어셈블리로 좀 보고 해결해 보고 싶어서 runtime error 잡아보고 싶었는데
unordered_map은 그냥 텍스트로 저장된 환경설정파일 속성값 나중에 더 추가될거 같아서 저장해놓고 두고두고 쓸라고 타입을 저렇게 둔건데 문제가 있나여?

익명 사용자의 이미지

mPreferenceVal.insert(someFileName, someProfertyValue);에서 someProfertyValue가 지역변수이기 때문에 위의 코드를 갖고 있는 함수가 종료된 시점에서 mPreferenceVal[someFileName이 갖고 있던 문자열]의 포인터 값은 유효한 값이 아니게 됩니다. 나중에 이 값으로 뭔가를 하기 시작하면 이제 지옥이 펼쳐지는 거죠. string으로 선언하면 값이 복사되므로 문제가 없고요. 포인터에 대해 좀 더 공부해 보시기 바랍니다.

ehaakdl의 이미지

insert할때 저는 해당 타입에 맞게 공간이 할당되는줄 알았습니다. 감사합니다.

...의 이미지

해당 타입이 뭔가 생각하시면 void*죠? 그러니까 공간 할당은 void*에 대해서 보통 4나 8바이트만 합니다. 그 값을 주소 삼아 찾아가면 나오는 object에 대한 공간은 할당하지 않구요.

그리고 향후 타입이 달라질지도 몰라서 void*를 쓴다고 하셨는데, 그게 STL이 template library인 이유고 템플릿을 쓰는 이유라고 생각합니다. 그게 아니라면 void*가 아니라 inheritance를 사용하는 게 맞다고 여겨집니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.