pxt-common-packages 9.3.10 → 9.3.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/libs/core---vm/vm.cpp +75 -2
- package/package.json +1 -1
package/libs/core---vm/vm.cpp
CHANGED
|
@@ -147,6 +147,78 @@ static inline void runAction(FiberContext *ctx, RefAction *ra) {
|
|
|
147
147
|
ctx->pc = actionPC(ra);
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
+
static const uint8_t *find_src_map() {
|
|
151
|
+
const uint32_t *p = (const uint32_t *)((uint32_t)vmImg->dataEnd & ~0xf);
|
|
152
|
+
const uint32_t *endP = p + 128;
|
|
153
|
+
while (p < endP) {
|
|
154
|
+
if (p[0] == 0x4d435253 && p[1] == 0x2d4e1588 && p[2] == 0x719986aa)
|
|
155
|
+
return (const uint8_t *)p;
|
|
156
|
+
p += 4;
|
|
157
|
+
}
|
|
158
|
+
DMESG("source map not found; dataEnd=%p", vmImg->dataEnd);
|
|
159
|
+
return NULL;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
static const uint8_t *decode_num(const uint8_t *p, int *dst) {
|
|
163
|
+
auto v = *p++;
|
|
164
|
+
if (v < 0xf0) {
|
|
165
|
+
*dst = v;
|
|
166
|
+
return p;
|
|
167
|
+
}
|
|
168
|
+
auto sz = v & 0x07;
|
|
169
|
+
int r = 0;
|
|
170
|
+
for (int i = 0; i < sz; ++i) {
|
|
171
|
+
r |= *p++ << (i * 8);
|
|
172
|
+
}
|
|
173
|
+
if (v & 0x08)
|
|
174
|
+
r = -r;
|
|
175
|
+
*dst = r;
|
|
176
|
+
return p;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
static const uint8_t *dump_pc_one(int addr, int off, const uint8_t *fn) {
|
|
180
|
+
if (!fn)
|
|
181
|
+
return NULL;
|
|
182
|
+
auto p = fn;
|
|
183
|
+
while (*p)
|
|
184
|
+
p++;
|
|
185
|
+
p++;
|
|
186
|
+
int prevLn = 0, prevOff = 0;
|
|
187
|
+
while (*p != 0xff) {
|
|
188
|
+
int a, b, c;
|
|
189
|
+
p = decode_num(p, &a);
|
|
190
|
+
p = decode_num(p, &b);
|
|
191
|
+
p = decode_num(p, &c);
|
|
192
|
+
prevLn += a;
|
|
193
|
+
b <<= 1;
|
|
194
|
+
prevOff += b;
|
|
195
|
+
c <<= 1;
|
|
196
|
+
|
|
197
|
+
int startA = prevOff;
|
|
198
|
+
int endA = startA + c;
|
|
199
|
+
if (startA <= addr + off && addr + off <= endA) {
|
|
200
|
+
DMESG(" PC:%x %s(%d)", addr, fn, prevLn);
|
|
201
|
+
return NULL;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return p + 1;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
static void dump_pc(int addr, const uint8_t *srcmap) {
|
|
208
|
+
if (srcmap) {
|
|
209
|
+
auto p = srcmap + 16;
|
|
210
|
+
for (;;) {
|
|
211
|
+
auto a = dump_pc_one(addr, -2, p);
|
|
212
|
+
if (!a || !dump_pc_one(addr, -4, p) || !dump_pc_one(addr, 0, p))
|
|
213
|
+
return;
|
|
214
|
+
p = a;
|
|
215
|
+
if (*p == 0)
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
DMESG(" PC:%x", addr);
|
|
220
|
+
}
|
|
221
|
+
|
|
150
222
|
void vm_stack_trace() {
|
|
151
223
|
auto ctx = currentFiber;
|
|
152
224
|
if (!ctx)
|
|
@@ -154,12 +226,13 @@ void vm_stack_trace() {
|
|
|
154
226
|
DMESG("stack trace (programHash:%d):", programHash());
|
|
155
227
|
auto end = vmImg->stackTop;
|
|
156
228
|
auto ptr = ctx->sp;
|
|
157
|
-
|
|
229
|
+
auto srcmap = find_src_map();
|
|
230
|
+
dump_pc((ctx->pc - ctx->imgbase) << 1, srcmap);
|
|
158
231
|
int max = 30;
|
|
159
232
|
while (ptr < end && max) {
|
|
160
233
|
auto v = (uintptr_t)*ptr++;
|
|
161
234
|
if (VM_IS_ENCODED_PC(v)) {
|
|
162
|
-
|
|
235
|
+
dump_pc(VM_DECODE_PC(v) << 1, srcmap);
|
|
163
236
|
max--;
|
|
164
237
|
}
|
|
165
238
|
}
|