Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ All notable changes to the Simics Target Debug extension will be documented here

### Fixed

- Source breakpoints no longer get a `target=` prefix on their file name
when the agent has a path map rule for the target file system, such as
`add-pathmap-entry "target=/host" ...` for binaries found by the Linux
tracker. Such breakpoints never resolved.
- The file pickers for symbol files now offer the standard file dialog, a `..` entry, and pick files in the
current folder ([#29](https://github.com/intel/simics-vs-code-tcf-debug/issues/29)).

Expand Down
14 changes: 14 additions & 0 deletions src/pathMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,13 +169,20 @@ export class PathMapper {
* Rules the agent got elsewhere, for example from the Simics command
* add-pathmap-entry, are not used by the agent for breakpoints, so those
* are applied in reverse here.
*
* Rules with a "target=" source are skipped. The Simics agent uses that
* prefix for files in the target's file system, such as binaries found
* by the OS awareness tracker, never for paths in the debug information.
*/
async toTarget(hostPath: string, contextId?: string): Promise<string> {
return (await this.toTargetLocation(hostPath, contextId)).path;
}

async toTargetLocation(hostPath: string, contextId?: string): Promise<TargetPath> {
for (const r of this.rules) {
if (isTargetFileSystemPath(r.source)) {
continue;
}
const p = mapPrefix(hostPath, r.destination, r.source);
const query = pathMapContextQuery(r);
if (p !== undefined && query && query !== "*" && query !== "**" && !contextId && !this.service) {
Expand All @@ -202,6 +209,9 @@ export class PathMapper {
}
}
for (const r of await this.otherAgentRules()) {
if (isTargetFileSystemPath(r.Source!)) {
continue;
}
const p = mapPrefix(hostPath, r.Destination!, r.Source!);
if (p !== undefined && (await this.matches(r.ContextQuery, contextId))) {
return {
Expand Down Expand Up @@ -400,6 +410,10 @@ export function mapPrefix(file: string, from: string, to: string): string | unde
return `${to.replace(/[\\/]+$/, "")}${rest}`;
}

function isTargetFileSystemPath(file: string): boolean {
return file.startsWith("target=");
}

function fileExists(file: string): boolean {
try {
return fs.statSync(file).isFile();
Expand Down
15 changes: 15 additions & 0 deletions src/test/pathMapper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,21 @@ test("toTarget maps agent rules for this host in reverse", async () => {
}
});

// Rules like add-pathmap-entry "target=/host" "/" map binaries the tracker
// reports in the target's file system. Source paths must not get the
// "target=" prefix, the debug information never contains it.
test("toTarget does not reverse rules for the target file system", async () => {
const fake = fakePathMapService([
{ Source: "target=/host/disk3", Destination: "/disk3" },
{ Source: "/build", Destination: "/disk3/ws" },
]);
const agent = new PathMapper([], fake.service);
assert.equal(await agent.toTarget("/disk3/src/a.c"), "/disk3/src/a.c");
assert.equal(await agent.toTarget("/disk3/ws/a.c"), "/build/a.c");
const local = new PathMapper([{ source: "target=/host/disk3", destination: "/disk3" }], undefined);
assert.equal(await local.toTarget("/disk3/src/a.c"), "/disk3/src/a.c");
});

// PathMap.get also returns our own rules. They must not be used as agent
// rules, since the agent already applies them.
test("toTarget skips the rules this client sent itself", async () => {
Expand Down