getsentry/symbolic

Bad symcache writing with split inlinees: The "parent" source location emitted for a "gap" in an inlinee can overwrite a previous inlinee

mstange opened this issue · 1 comments

There's a problem with this code:

// if `line` ends before `parent_line`, we need to insert another range for the leftover piece.
if let Some(size) = line.size {
let line_end = line.address + size;
if let Some(parent_size) = parent_line.size {
let parent_end = parent_line.address + parent_size;
if line_end == parent_end {
continue;
}
}
self.ranges.insert(line_end as u32, caller_source_location);
}

A previous inlinee may already have written something valuable at the line_end address, and that's now getting overwritten.

I'll try and see if I can find an example in a PDB.

Ah, this can only happen if the parent's line record spans both inlinee A and and the first chunk of inlinee B, with inlinee A sitting in the gap between inlinee B's two chunks. This should only happen if both A and B are called from the same line in the parent, which is probably rare.

Synthetic Function:

Function {
  name: "outer",
  lines: [Line { address: 0x1000, size: 0x30, file: "main.rs", line: 5 }],
  inlinees: [
    Function {
      name: "inlineeA",
      lines: [Line { address: 0x1010, size: 0x10, file: "main.rs", line: 20 }],
      inlinees: [],
    },
    Function {
      name: "inlineeB",
      lines: [
        Line { address: 0x1000, size: 0x10, file: "main.rs", line: 40 },
        Line { address: 0x1020, size: 0x10, file: "main.rs", line: 42 }
      ],
      inlinees: [],
    },
  ]
}