Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit 2f5ff93

Browse files
committed
Reset lastAddress to 0 on sequence end + use first file:line found for address
1 parent 068be2e commit 2f5ff93

File tree

1 file changed

+53
-25
lines changed

1 file changed

+53
-25
lines changed

src/rt/backtrace/dwarf.d

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import rt.backtrace.elf;
1919

2020
import core.stdc.string : strlen, memchr;
2121

22+
//debug = DwarfDebugMachine;
23+
2224
struct Location
2325
{
2426
const(char)[] file = null; // file is missing directory, but DMD emits directory directly into file
@@ -94,11 +96,14 @@ private:
9496
// the lifetime of the Location data is the lifetime of the mmapped ElfSection
9597
void resolveAddresses(ElfSection* debugLineSection, Location[] locations) @nogc nothrow
9698
{
99+
debug(DwarfDebugMachine) import core.stdc.stdio;
100+
97101
size_t numberOfLocationsFound = 0;
98102

99103
const(ubyte)[] dbg = debugLineSection.get();
100104
while (dbg.length > 0)
101105
{
106+
debug(DwarfDebugMachine) printf("new debug program\n");
102107
const(LPHeader)* lph = cast(const(LPHeader)*) dbg.ptr;
103108

104109
if (lph.unitLength == 0xffff_ffff) // is 64-bit dwarf?
@@ -137,6 +142,7 @@ void resolveAddresses(ElfSection* debugLineSection, Location[] locations) @nogc
137142
while (pathData[0] != 0)
138143
{
139144
directories[currentDirectoryIndex] = cast(const(char)[]) pathData[0 .. strlen(cast(char*) (pathData.ptr))];
145+
debug(DwarfDebugMachine) printf("dir: %s\n", pathData.ptr);
140146
pathData = pathData[directories[currentDirectoryIndex].length + 1 .. $];
141147
currentDirectoryIndex++;
142148
}
@@ -165,6 +171,7 @@ void resolveAddresses(ElfSection* debugLineSection, Location[] locations) @nogc
165171
while (pathData[0] != 0)
166172
{
167173
filenames[currentFileIndex] = cast(const(char)[]) pathData[0 .. strlen(cast(char*) (pathData.ptr))];
174+
debug(DwarfDebugMachine) printf("file: %s\n", pathData.ptr);
168175
pathData = pathData[filenames[currentFileIndex].length + 1 .. $];
169176

170177
auto dirIndex = pathData.readULEB128(); // unused
@@ -177,27 +184,46 @@ void resolveAddresses(ElfSection* debugLineSection, Location[] locations) @nogc
177184
LocationInfo lastLoc = LocationInfo(-1, -1);
178185
size_t lastAddress = 0x0;
179186

187+
debug(DwarfDebugMachine) printf("program:\n");
180188
runStateMachine(lph, program, standardOpcodeLengths,
181-
(size_t address, LocationInfo locInfo)
189+
(size_t address, LocationInfo locInfo, bool isEndSequence)
182190
{
183-
foreach (ref loc; locations)
191+
// If loc.line != -1, then it has been set previously.
192+
// Some implementations (eg. dmd) write an address to
193+
// the debug data multiple times, but so far I have found
194+
// that the first occurrence to be the correct one.
195+
foreach (ref loc; locations) if (loc.line == -1)
184196
{
185197
if (loc.address == address)
186198
{
199+
debug(DwarfDebugMachine) printf("-- found for [0x%x]:\n", loc.address);
200+
debug(DwarfDebugMachine) printf("-- file: %.*s\n", filenames[locInfo.file - 1].length, filenames[locInfo.file - 1].ptr);
201+
debug(DwarfDebugMachine) printf("-- line: %d\n", locInfo.line);
187202
loc.file = filenames[locInfo.file - 1];
188203
loc.line = locInfo.line;
189204
numberOfLocationsFound++;
190205
}
191206
else if (loc.address < address && lastAddress < loc.address && lastAddress != 0)
192207
{
208+
debug(DwarfDebugMachine) printf("-- found for [0x%x]:\n", loc.address);
209+
debug(DwarfDebugMachine) printf("-- file: %.*s\n", filenames[lastLoc.file - 1].length, filenames[lastLoc.file - 1].ptr);
210+
debug(DwarfDebugMachine) printf("-- line: %d\n", lastLoc.line);
193211
loc.file = filenames[lastLoc.file - 1];
194212
loc.line = lastLoc.line;
195213
numberOfLocationsFound++;
196214
}
197215
}
198216

199-
lastAddress = address;
200-
lastLoc = locInfo;
217+
if (isEndSequence)
218+
{
219+
lastAddress = 0;
220+
}
221+
else
222+
{
223+
lastAddress = address;
224+
lastLoc = locInfo;
225+
}
226+
201227
return numberOfLocationsFound < locations.length;
202228
}
203229
);
@@ -207,9 +233,11 @@ void resolveAddresses(ElfSection* debugLineSection, Location[] locations) @nogc
207233
}
208234
}
209235

210-
alias RunStateMachineCallback = bool delegate(size_t, LocationInfo) @nogc nothrow;
236+
alias RunStateMachineCallback = bool delegate(size_t, LocationInfo, bool) @nogc nothrow;
211237
bool runStateMachine(const(LPHeader)* lpHeader, const(ubyte)[] program, const(ubyte)[] standardOpcodeLengths, scope RunStateMachineCallback callback) @nogc nothrow
212238
{
239+
debug(DwarfDebugMachine) import core.stdc.stdio;
240+
213241
StateMachine machine;
214242
machine.isStatement = lpHeader.defaultIsStatement;
215243

@@ -228,98 +256,98 @@ bool runStateMachine(const(LPHeader)* lpHeader, const(ubyte)[] program, const(ub
228256
{
229257
case endSequence:
230258
machine.isEndSequence = true;
231-
// trace("endSequence ", "0x%x".format(m.address));
232-
if (!callback(machine.address, LocationInfo(machine.fileIndex, machine.line))) return true;
259+
debug(DwarfDebugMachine) printf("endSequence 0x%x\n", machine.address);
260+
if (!callback(machine.address, LocationInfo(machine.fileIndex, machine.line), true)) return true;
233261
machine = StateMachine.init;
234262
machine.isStatement = lpHeader.defaultIsStatement;
235263
break;
236264

237265
case setAddress:
238266
size_t address = program.read!size_t();
239-
// trace("setAddress ", "0x%x".format(address));
267+
debug(DwarfDebugMachine) printf("setAddress 0x%x\n", address);
240268
machine.address = address;
241269
break;
242270

243271
case defineFile: // TODO: add proper implementation
244-
// trace("defineFile");
272+
debug(DwarfDebugMachine) printf("defineFile\n");
245273
program = program[len - 1 .. $];
246274
break;
247275

248276
default:
249277
// unknown opcode
250-
// trace("unknown extended opcode ", eopcode);
278+
debug(DwarfDebugMachine) printf("unknown extended opcode %d\n", cast(int) eopcode);
251279
program = program[len - 1 .. $];
252280
break;
253281
}
254282

255283
break;
256284

257285
case copy:
258-
// trace("copy");
259-
if (!callback(machine.address, LocationInfo(machine.fileIndex, machine.line))) return true;
286+
debug(DwarfDebugMachine) printf("copy 0x%x\n", machine.address);
287+
if (!callback(machine.address, LocationInfo(machine.fileIndex, machine.line), false)) return true;
260288
machine.isBasicBlock = false;
261289
machine.isPrologueEnd = false;
262290
machine.isEpilogueBegin = false;
263291
break;
264292

265293
case advancePC:
266294
ulong op = readULEB128(program);
267-
// trace("advancePC ", op * lpHeader.minimumInstructionLength);
268295
machine.address += op * lpHeader.minimumInstructionLength;
296+
debug(DwarfDebugMachine) printf("advancePC %d to 0x%x\n", cast(int) (op * lpHeader.minimumInstructionLength), machine.address);
269297
break;
270298

271299
case advanceLine:
272300
long ad = readSLEB128(program);
273-
// trace("advanceLine ", ad);
274301
machine.line += ad;
302+
debug(DwarfDebugMachine) printf("advanceLine %d to %d\n", cast(int) ad, cast(int) machine.line);
275303
break;
276304

277305
case setFile:
278306
uint index = cast(uint) readULEB128(program);
279-
// trace("setFile to ", index);
307+
debug(DwarfDebugMachine) printf("setFile to %d\n", cast(int) index);
280308
machine.fileIndex = index;
281309
break;
282310

283311
case setColumn:
284312
uint col = cast(uint) readULEB128(program);
285-
// trace("setColumn ", col);
313+
debug(DwarfDebugMachine) printf("setColumn %d\n", cast(int) col);
286314
machine.column = col;
287315
break;
288316

289317
case negateStatement:
290-
// trace("negateStatement");
318+
debug(DwarfDebugMachine) printf("negateStatement\n");
291319
machine.isStatement = !machine.isStatement;
292320
break;
293321

294322
case setBasicBlock:
295-
// trace("setBasicBlock");
323+
debug(DwarfDebugMachine) printf("setBasicBlock\n");
296324
machine.isBasicBlock = true;
297325
break;
298326

299327
case constAddPC:
300328
machine.address += (255 - lpHeader.opcodeBase) / lpHeader.lineRange * lpHeader.minimumInstructionLength;
301-
// trace("constAddPC ", "0x%x".format(machine.address));
329+
debug(DwarfDebugMachine) printf("constAddPC 0x%x\n", machine.address);
302330
break;
303331

304332
case fixedAdvancePC:
305333
uint add = program.read!uint();
306-
// trace("fixedAdvancePC ", add);
307334
machine.address += add;
335+
debug(DwarfDebugMachine) printf("fixedAdvancePC %d to 0x%x\n", cast(int) add, machine.address);
308336
break;
309337

310338
case setPrologueEnd:
311339
machine.isPrologueEnd = true;
312-
// trace("setPrologueEnd");
340+
debug(DwarfDebugMachine) printf("setPrologueEnd\n");
313341
break;
314342

315343
case setEpilogueBegin:
316344
machine.isEpilogueBegin = true;
317-
// trace("setEpilogueBegin");
345+
debug(DwarfDebugMachine) printf("setEpilogueBegin\n");
318346
break;
319347

320348
case setISA:
321349
machine.isa = cast(uint) readULEB128(program);
322-
// trace("setISA ", m.isa);
350+
debug(DwarfDebugMachine) printf("setISA %d\n", cast(int) machine.isa);
323351
break;
324352

325353
default:
@@ -335,8 +363,8 @@ bool runStateMachine(const(LPHeader)* lpHeader, const(ubyte)[] program, const(ub
335363
auto linc = lpHeader.lineBase + (opcode % lpHeader.lineRange);
336364
machine.line += linc;
337365

338-
// trace("special ", ainc, " ", linc);
339-
if (!callback(machine.address, LocationInfo(machine.fileIndex, machine.line))) return true;
366+
debug(DwarfDebugMachine) printf("special %d %d to 0x%x line %d\n", cast(int) ainc, cast(int) linc, machine.address, cast(int) machine.line);
367+
if (!callback(machine.address, LocationInfo(machine.fileIndex, machine.line), false)) return true;
340368
}
341369
}
342370

0 commit comments

Comments
 (0)