aboutsummaryrefslogtreecommitdiff
path: root/acid/leak
blob: 6231f950f025cfb44f545916cf9fadea6aa27994 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//
// usage: acid -l pool -l leak
//
include("/sys/src/libc/port/pool.acid");

defn
dumppool(p)
{
	complex Pool p;
	a = p.arenalist;

	while a != 0 && a < 0x60000000 do {
		complex Arena a;
		dumparena(a);
		a = a.down;
	}
}

defn
dumparena(arena)
{
	local atail, b, nb;

	atail = A2TB(arena);
	complex Bhdr arena;
	b = a;
	while b < atail && b.magic != ARENATAIL_MAGIC do {
		dumpblock(b);
		nb = B2NB(b);
		if nb == b then {
			print("B2NB(", b\X, ") = b\n");
			b = atail;	// end loop
		}
		if nb > atail then {
			b = (Bhdr)(b+4);
			print("lost at block ", (b-4)\X, ", scanning forward\n");
			while b < atail && b.magic != KEMPT_MAGIC && b.magic != FREE_MAGIC do
				b = (Bhdr)(b+4);
			print("stopped at ", b\X, " ", *b\X, "\n");
		}else
			b = nb;
	}
	if b != atail then
		print("found wrong tail to arena ", arena\X, " wanted ", atail\X, "\n");
}

defn
isptr(a)
{
	if end <= a && a < xbloc then
		return 1;
	if 0x7efff000 <= a && a < 0x7ffff000 then
		return 1;
	return 0;
}

defn
dumpblock(addr)
{
	complex Bhdr addr;

	if addr.magic == KEMPT_MAGIC || addr.magic == FREE_MAGIC then {
		local a, x, s;

		a = addr;
		complex Alloc a;

		x = addr+8;
		if addr.magic == KEMPT_MAGIC then
			s = "block";
		else
			s = "free";
		print(s, " ", addr\X, " ", a.size\X, " ");
		print(*(addr+8)\X, " ", *(addr+12)\X, "\n");
	}
}

defn
dumprange(s, e, type)
{
	local x, y;

	print("range ", type, " ", s\X, " ", e\X, "\n");
	x = s;
	while x < e do {
		y = *x;
		if isptr(y) then print("data ", x\X, " ", y\X, " ", type, "\n");
		x = x + 4;
	}
}

defn
dumpmem()
{
	local s;

	xbloc = *bloc;
	// assume map()[1] is "data" 
	dumprange(map()[1][1], end, "bss");	// bss
	dumprange(end, xbloc, "alloc");	// allocated

	if 0x7efff000 < *SP && *SP < 0x7ffff000 then 
		s = *SP;
	else
		s = 0x7fff7000;	// 32 k

	dumprange(s, 0x7ffff000, "stack");
}

defn
dumpregs()
{
	dumprange(0, sizeofUreg, "reg");
}


defn
leakdump(l)
{
	print("==LEAK BEGIN==\n");
	dumppool(sbrkmem);
	dumpmem();
	dumpregs();
	while l != {} do {
		setproc(head l);
		dumpregs();
		l = tail l;
	}
	print("==LEAK END==\n");
}

defn
blockdump()
{
	print("==BLOCK BEGIN==\n");
	dumppool(sbrkmem);
	print("==BLOCK END==\n");
}