Skip to content

Commit

Permalink
Use -fdebug-prefix-map to map headers to source location
Browse files Browse the repository at this point in the history
Summary:
We compile against the symlinked headers rather than the source headers,
this means debug info includes the symlink path rather than source path
which causes IDE debugging to fail. Let's use `-fdebug-prefix-map` to embed
the source location into the DIE instead.

User reporting link: https://fb.workplace.com/groups/native.debugging/posts/1603445763372598

Reviewed By: bobyangyf

Differential Revision: D43288653

fbshipit-source-id: 1861f5dd26fdbf97c9bc1a93a7f13315870191a7
  • Loading branch information
Christy Lee-Eusman authored and facebook-github-bot committed Feb 23, 2023
1 parent d1e36ed commit b95594e
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
25 changes: 23 additions & 2 deletions cxx/headers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ Headers = record(
include_path = field("cmd_args"),
# NOTE(agallagher): Used for module hack replacement.
symlink_tree = field(["artifact", None], None),
preprocessor_args = field(["cmd_args", None], None),
)

CHeader = record(
Expand Down Expand Up @@ -183,18 +184,24 @@ def prepare_headers(ctx: "context", srcs: {str.type: "artifact"}, name: str.type
is_any(lambda n: paths.basename(n) == "module.modulemap", srcs.keys())):
header_mode = HeaderMode("symlink_tree_only")
if header_mode == HeaderMode("header_map_only"):
hmap = _mk_hmap(ctx, name, {h: (a, "{}") for h, a in srcs.items()})
headers = {h: (a, "{}") for h, a in srcs.items()}
hmap = _mk_hmap(ctx, name, headers)
preprocessor_args = _get_debug_prefix_args(ctx, headers)
return Headers(
include_path = cmd_args(hmap).hidden(srcs.values()),
preprocessor_args = preprocessor_args,
)
symlink_dir = ctx.actions.symlinked_dir(name, _normalize_header_srcs(srcs))
if header_mode == HeaderMode("symlink_tree_only"):
return Headers(include_path = cmd_args(symlink_dir), symlink_tree = symlink_dir)
if header_mode == HeaderMode("symlink_tree_with_header_map"):
hmap = _mk_hmap(ctx, name, {h: (symlink_dir, "{}/" + h) for h in srcs})
headers = {h: (symlink_dir, "{}/" + h) for h in srcs}
hmap = _mk_hmap(ctx, name, headers)
preprocessor_args = _get_debug_prefix_args(ctx, headers)
return Headers(
include_path = cmd_args(hmap).hidden(symlink_dir),
symlink_tree = symlink_dir,
preprocessor_args = preprocessor_args,
)
fail("Unsupported header mode: {}".format(header_mode))

Expand Down Expand Up @@ -303,6 +310,20 @@ def _get_dict_header_namespace(namespace: str.type, naming: CxxHeadersNaming.typ
else:
fail("Unsupported header naming: {}".format(naming))

def _get_debug_prefix_args(ctx: "context", headers: {str.type: ("artifact", str.type)}) -> [cmd_args.type, None]:
# NOTE(@christylee): Do we need to enable debug-prefix-map for darwin and windows?
if get_cxx_toolchain_info(ctx).linker_info.type != "gnu":
return None

debug_prefix_args = cmd_args()

for path, _ in headers.values():
fmt = "-fdebug-prefix-map={}=" + value_or(path.owner.cell, ".")
debug_prefix_args.add(
cmd_args(path, format = fmt),
)
return debug_prefix_args

def _mk_hmap(ctx: "context", name: str.type, headers: {str.type: ("artifact", str.type)}) -> "artifact":
output = ctx.actions.declare_output(name + ".hmap")
cmd = cmd_args(get_cxx_toolchain_info(ctx).mk_hmap)
Expand Down
4 changes: 4 additions & 0 deletions cxx/preprocessor.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ def cxx_exported_preprocessor_info(ctx: "context", headers_layout: CxxHeadersLay
if header_root != None:
inc_flag = _header_style_flag(style)
args.extend([inc_flag, header_root.include_path])
if header_root.preprocessor_args != None:
args.append(header_root.preprocessor_args)

# Embed raw headers as hidden artifacts in our args. This means downstream
# cases which use these args don't also need to know to add raw headers.
Expand Down Expand Up @@ -292,6 +294,8 @@ def _cxx_private_preprocessor_info(
header_root = prepare_headers(ctx, header_map, "buck-private-headers")
if header_root != None:
args.extend(["-I", header_root.include_path])
if header_root.preprocessor_args != None:
args.append(header_root.preprocessor_args)

# Embed raw headers as hidden artifacts in our args. This means downstream
# cases which use these args don't also need to know to add raw headers.
Expand Down

0 comments on commit b95594e

Please sign in to comment.