BayGC/06


Top / BayGC / 06

スタックの走査

前回までで、スタックの構造がわかったので、スタックを走査してみます。

ソースコード

ebp と esp を取っておいて、スタックを走査しています。ebp と esp を C++ から取得する方法はないので、インラインアセンブラを使っています。

#include <stdio.h>
#include <stdlib.h>

char* ebp;
char* esp;

void gc(){
	asm volatile("movl %%esp, %0" : "=g"(esp));
	int start = (int) esp;
	int end   = (int) ebp;
	printf("esp = %p\n", start);
	printf("ebp = %p\n", end);
	for (int i = 0; i < end - start; i++) {
		printf("%p = %p\n", &esp[i], esp[i] & 0xff);
	}
}

void test1() {
	int   a = 0x11112222;
	short b = 0x1234;
	char  c = 0x12;
	char  d = 0x34;
}

void test2() {
	gc();
}

int main() {
	asm volatile("movl %%ebp, %0" : "=g"(ebp));
	test1();
	test2();
	return 0;
}

実行

g++ 3.cpp
./a.exe
esp = 0x22cca0
ebp = 0x22cce8
(中略)
0x22ccbe = 0x40
0x22ccbf = 0x0
0x22ccc0 = 0x34
0x22ccc1 = 0x12
0x22ccc2 = 0x34
0x22ccc3 = 0x12
0x22ccc4 = 0x22
0x22ccc5 = 0x22
0x22ccc6 = 0x11
0x22ccc7 = 0x11
0x22ccc8 = 0xe8
0x22ccc9 = 0xcc
(中略)

0x11112222, 0x1234, 0x12, 0x34 がなかよく並んでいるところが見つかりました!!もし、int a = 0x1234 の代わりに、 int *a = new int; とすれば、ポインター a のアドレスが入ってくるはずです。実際にやってみます。

ソースコード

new したときに返ってくるアドレスをデバッグ用に表示したかったため、new 演算子をオーバーライドしました。また、gc 検出用に new int を無駄にたくさん呼んでみました。

#include <stdio.h>
#include <stdlib.h>

char* ebp;
char* esp;

void gc(){
	asm volatile("movl %%esp, %0" : "=g"(esp));
	int start = (int) esp;
	int end   = (int) ebp;
	printf("esp = %p\n", start);
	printf("ebp = %p\n", end);
	for (int i = 0; i < end - start; i++) {
		printf("%p = %02x\n", &esp[i], esp[i] & 0xff);
	}
}

void* operator new(unsigned int size) {
	void* ret = malloc(size);
	printf("operator new(%d) = %p\n", size, ret);
	return ret;
}

void test1() {
	int* a = new int;
	int* b = new int;
	int* c = new int;
	int* d = new int;
	int* e = new int;
}

void test2() {
	gc();
}

int main() {
	asm volatile("movl %%ebp, %0" : "=g"(ebp));
	test1();
	test2();
	return 0;
}

実行

g++ 4.cpp
./a.exe
operator new(4) = 0x660140
operator new(4) = 0x660558
operator new(4) = 0x660568
operator new(4) = 0x660578
operator new(4) = 0x660588
esp = 0x22cca0
ebp = 0x22cce8
(中略)
0x22ccbe = 0x40
0x22ccbf = 0x00
0x22ccc0 = 0x58 -+
0x22ccc1 = 0x05  | 0x660558
0x22ccc2 = 0x66  |
0x22ccc3 = 0x00 -+
0x22ccc4 = 0x40 -+
0x22ccc5 = 0x01  | 0x660140
0x22ccc6 = 0x66  |
0x22ccc7 = 0x00 -+
0x22ccc8 = 0xe8
0x22ccc9 = 0xcc
(中略)

確かに、new で確保したアドレスが入っているようです。しかし、5つ確保したのに、2つしか見つかりません。ソースをよく見れば、それもそのはずで、gc は割と頻繁に呼んでやらないとメモリリークすることがわかります。

MENU

now: 2

リンク


最新の20件
2017-09-29 2017-04-25 2017-01-10 2016-12-11 2016-12-09 2016-10-04 2016-08-14 2016-06-05 2016-05-29 2016-04-15 2015-12-28 2013-02-25 2013-02-21 2013-02-20 2013-02-12 2013-02-11 2013-02-10
最新の20件
2010-02-01 2010-01-31 2010-01-30 2010-01-29 2010-01-16

Counter: 2080, today: 2, yesterday: 0

リロード   新規 編集 凍結 差分 添付 複製 改名   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS

Last-modified: 2008-03-28 (金) 15:47:54 (3676d);  Modified by mona
PukiWiki 1.4.6 Copyright © 2001-2005 PukiWiki Developers Team. License is GPL.
Based on "PukiWiki" 1.3 by yu-ji
Powered by PHP 5.2.17
HTML convert time to 0.028 sec.