Skip to content

Commit

Permalink
[5.9] pass -fno-omit-frame-pointer in support of new backtracer (#7042)…
Browse files Browse the repository at this point in the history
… (#7049)

5.9 cherry pick of #7042
  • Loading branch information
tomerd authored Nov 7, 2023
1 parent 732d540 commit ef57d9f
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 6 deletions.
11 changes: 11 additions & 0 deletions Sources/Build/BuildDescription/ClangTargetBuildDescription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,17 @@ public final class ClangTargetBuildDescription {
args += self.buildParameters.flags.cxxCompilerFlags
}

// rdar://117578677
// Pass -fno-omit-frame-pointer to support backtraces
// this can be removed once the backtracer uses DWARF instead of frame pointers
if let omitFramePointers = self.buildParameters.omitFramePointers {
if omitFramePointers {
args += ["-fomit-frame-pointer"]
} else {
args += ["-fno-omit-frame-pointer"]
}
}

// Pass default include paths from the toolchain.
for includeSearchPath in self.buildParameters.toolchain.includeSearchPaths {
args += ["-I", includeSearchPath.pathString]
Expand Down
11 changes: 11 additions & 0 deletions Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,17 @@ public final class SwiftTargetBuildDescription {

args += self.packageNameArgumentIfSupported(with: self.package, packageAccess: self.target.packageAccess)
args += try self.macroArguments()

// rdar://117578677
// Pass -fno-omit-frame-pointer to support backtraces
// this can be removed once the backtracer uses DWARF instead of frame pointers
if let omitFramePointers = self.buildParameters.omitFramePointers {
if omitFramePointers {
args += ["-Xcc", "-fomit-frame-pointer"]
} else {
args += ["-Xcc", "-fno-omit-frame-pointer"]
}
}

return args
}
Expand Down
5 changes: 5 additions & 0 deletions Sources/CoreCommands/Options.swift
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,11 @@ public struct BuildOptions: ParsableArguments {
)
public var testEntryPointPath: AbsolutePath?

// Whether to omit frame pointers
// this can be removed once the backtracer uses DWARF instead of frame pointers
@Flag(inversion: .prefixedNo, help: .hidden)
public var omitFramePointers: Bool? = nil

// @Flag works best when there is a default value present
// if true, false aren't enough and a third state is needed
// nil should not be the goto. Instead create an enum
Expand Down
1 change: 1 addition & 0 deletions Sources/CoreCommands/SwiftTool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,7 @@ public final class SwiftTool {
isXcodeBuildSystemEnabled: options.build.buildSystem == .xcode,
forceTestDiscovery: options.build.enableTestDiscovery, // backwards compatibility, remove with --enable-test-discovery
testEntryPointPath: options.build.testEntryPointPath,
omitFramePointers: options.build.omitFramePointers,
explicitTargetDependencyImportCheckingMode: options.build.explicitTargetDependencyImportCheck.modeParameter,
linkerDeadStrip: options.linker.linkerDeadStrip,
verboseOutput: self.logLevel <= .info
Expand Down
5 changes: 5 additions & 0 deletions Sources/SPMBuildCore/BuildParameters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ public struct BuildParameters: Encodable {
/// The style of test product to produce.
public var testProductStyle: TestProductStyle

/// Whether to omit or preserver frame pointers
public var omitFramePointers: Bool?

/// Whether to disable dead code stripping by the linker
public var linkerDeadStrip: Bool

Expand Down Expand Up @@ -247,6 +250,7 @@ public struct BuildParameters: Encodable {
enableTestability: Bool? = nil,
forceTestDiscovery: Bool = false,
testEntryPointPath: AbsolutePath? = nil,
omitFramePointers: Bool? = nil,
explicitTargetDependencyImportCheckingMode: TargetDependencyImportCheckingMode = .none,
linkerDeadStrip: Bool = true,
colorizedOutput: Bool = false,
Expand Down Expand Up @@ -287,6 +291,7 @@ public struct BuildParameters: Encodable {
explicitlyEnabledDiscovery: forceTestDiscovery,
explicitlySpecifiedPath: testEntryPointPath
)
self.omitFramePointers = omitFramePointers ?? (triple.isLinux() ? false : nil)
self.explicitTargetDependencyImportCheckingMode = explicitTargetDependencyImportCheckingMode
self.linkerDeadStrip = linkerDeadStrip
self.colorizedOutput = colorizedOutput
Expand Down
85 changes: 80 additions & 5 deletions Tests/BuildTests/BuildPlanTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1190,6 +1190,11 @@ final class BuildPlanTests: XCTestCase {
#if !os(Windows) // FIXME(5473) - modules flags on Windows dropped
args += ["-fmodules-cache-path=\(buildPath.appending(components: "ModuleCache"))"]
#endif

if hostTriple.isLinux() {
args += ["-fno-omit-frame-pointer"]
}

XCTAssertEqual(try ext.basicArguments(isCXX: false), args)
XCTAssertEqual(try ext.objects, [buildPath.appending(components: "extlib.build", "extlib.c.o")])
XCTAssertEqual(ext.moduleMap, buildPath.appending(components: "extlib.build", "module.modulemap"))
Expand Down Expand Up @@ -1222,6 +1227,11 @@ final class BuildPlanTests: XCTestCase {
#if !os(Windows) // FIXME(5473) - modules flags on Windows dropped
args += ["-fmodules-cache-path=\(buildPath.appending(components: "ModuleCache"))"]
#endif

if hostTriple.isLinux() {
args += ["-fno-omit-frame-pointer"]
}

XCTAssertEqual(try exe.basicArguments(isCXX: false), args)
XCTAssertEqual(try exe.objects, [buildPath.appending(components: "exe.build", "main.c.o")])
XCTAssertEqual(exe.moduleMap, nil)
Expand Down Expand Up @@ -1453,7 +1463,7 @@ final class BuildPlanTests: XCTestCase {
XCTAssertMatch(contents, .contains(#"-std=c++1z","-c","\#(Pkg.appending(components: "Sources", "lib", "libx.cpp").escapedPathString())"#))

let swiftInteropLib = try result.target(for: "swiftInteropLib").swiftTarget().compileArguments()
XCTAssertMatch(swiftInteropLib, [.anySequence, "-cxx-interoperability-mode=default", "-Xcc", "-std=c++1z", .end])
XCTAssertMatch(swiftInteropLib, [.anySequence, "-cxx-interoperability-mode=default", "-Xcc", "-std=c++1z", .anySequence])
let swiftLib = try result.target(for: "swiftLib").swiftTarget().compileArguments()
XCTAssertNoMatch(swiftLib, [.anySequence, "-Xcc", "-std=c++1z", .anySequence])
}
Expand Down Expand Up @@ -1516,6 +1526,11 @@ final class BuildPlanTests: XCTestCase {
#if !os(Windows) // FIXME(5473) - modules flags on Windows dropped
args += ["-fmodules-cache-path=\(buildPath.appending(components: "ModuleCache"))"]
#endif

if hostTriple.isLinux() {
args += ["-fno-omit-frame-pointer"]
}

XCTAssertEqual(try lib.basicArguments(isCXX: false), args)
XCTAssertEqual(try lib.objects, [buildPath.appending(components: "lib.build", "lib.c.o")])
XCTAssertEqual(lib.moduleMap, buildPath.appending(components: "lib.build", "module.modulemap"))
Expand Down Expand Up @@ -2480,6 +2495,11 @@ final class BuildPlanTests: XCTestCase {
#if !os(Windows) // FIXME(5473) - modules flags on Windows dropped
expectedExeBasicArgs += ["-fmodules-cache-path=\(buildPath.appending(components: "ModuleCache"))"]
#endif

if triple.isLinux() {
expectedExeBasicArgs += ["-fno-omit-frame-pointer"]
}

XCTAssertEqual(try exe.basicArguments(isCXX: false), expectedExeBasicArgs)
XCTAssertEqual(try exe.objects, [buildPath.appending(components: "exe.build", "main.c.o")])
XCTAssertEqual(exe.moduleMap, nil)
Expand All @@ -2498,6 +2518,11 @@ final class BuildPlanTests: XCTestCase {
if shouldHaveModules {
expectedLibBasicArgs += ["-fmodules-cache-path=\(buildPath.appending(components: "ModuleCache"))"]
}

if triple.isLinux() {
expectedLibBasicArgs += ["-fno-omit-frame-pointer"]
}

XCTAssertEqual(try lib.basicArguments(isCXX: true), expectedLibBasicArgs)

XCTAssertEqual(try lib.objects, [buildPath.appending(components: "lib.build", "lib.cpp.o")])
Expand Down Expand Up @@ -3382,21 +3407,71 @@ final class BuildPlanTests: XCTestCase {
let result = try createResult(for: .x86_64Linux)

let dep = try result.target(for: "t1").swiftTarget().compileArguments()
XCTAssertMatch(dep, [.anySequence, "-DDEP", .end])
XCTAssertMatch(dep, [.anySequence, "-DDEP", "-Xcc", "-fno-omit-frame-pointer", .end])

let cbar = try result.target(for: "cbar").clangTarget().basicArguments(isCXX: false)
XCTAssertMatch(cbar, [.anySequence, "-DCCC=2", "-I\(A.appending(components: "Sources", "cbar", "Sources", "headers"))", "-I\(A.appending(components: "Sources", "cbar", "Sources", "cppheaders"))", "-Icfoo", "-L", "cbar", "-Icxxfoo", "-L", "cxxbar", .end])
XCTAssertMatch(cbar, [.anySequence, "-DCCC=2", "-I\(A.appending(components: "Sources", "cbar", "Sources", "headers"))", "-I\(A.appending(components: "Sources", "cbar", "Sources", "cppheaders"))", "-Icfoo", "-L", "cbar", "-Icxxfoo", "-L", "cxxbar", "-fno-omit-frame-pointer", .end])

let bar = try result.target(for: "bar").swiftTarget().compileArguments()
XCTAssertMatch(bar, [.anySequence, "-DLINUX", "-Isfoo", "-L", "sbar", "-cxx-interoperability-mode=default", "-enable-upcoming-feature", "BestFeature", .end])
XCTAssertMatch(bar, [.anySequence, "-DLINUX", "-Isfoo", "-L", "sbar", "-cxx-interoperability-mode=default", "-enable-upcoming-feature", "BestFeature", "-Xcc", "-fno-omit-frame-pointer", .end])

let exe = try result.target(for: "exe").swiftTarget().compileArguments()
XCTAssertMatch(exe, [.anySequence, "-DFOO", .end])
XCTAssertMatch(exe, [.anySequence, "-DFOO", "-Xcc", "-fno-omit-frame-pointer", .end])

let linkExe = try result.buildProduct(for: "exe").linkArguments()
XCTAssertMatch(linkExe, [.anySequence, "-lsqlite3", "-llibz", "-framework", "best", "-Ilfoo", "-L", "lbar", .end])
}

// omit frame pointers explicitly set to true
do {
let result = try BuildPlanResult(plan: BuildPlan(
buildParameters: mockBuildParameters(
destinationTriple: .x86_64Linux,
omitFramePointers: true
),
graph: graph,
fileSystem: fs,
observabilityScope: observability.topScope
))

let dep = try result.target(for: "t1").swiftTarget().compileArguments()
XCTAssertMatch(dep, [.anySequence, "-DDEP", .anySequence])

let cbar = try result.target(for: "cbar").clangTarget().basicArguments(isCXX: false)
XCTAssertMatch(cbar, [.anySequence, "-DCCC=2", "-I\(A.appending(components: "Sources", "cbar", "Sources", "headers"))", "-I\(A.appending(components: "Sources", "cbar", "Sources", "cppheaders"))", "-Icfoo", "-L", "cbar", "-Icxxfoo", "-L", "cxxbar", "-fomit-frame-pointer", .end])

let bar = try result.target(for: "bar").swiftTarget().compileArguments()
XCTAssertMatch(bar, [.anySequence, "-DLINUX", "-Isfoo", "-L", "sbar", "-cxx-interoperability-mode=default", "-enable-upcoming-feature", "BestFeature", "-Xcc", "-fomit-frame-pointer", .end])

let exe = try result.target(for: "exe").swiftTarget().compileArguments()
XCTAssertMatch(exe, [.anySequence, "-DFOO", "-Xcc", "-fomit-frame-pointer", .end])
}

// omit frame pointers explicitly set to false
do {
let result = try BuildPlanResult(plan: BuildPlan(
buildParameters: mockBuildParameters(
destinationTriple: .x86_64Linux,
omitFramePointers: false
),
graph: graph,
fileSystem: fs,
observabilityScope: observability.topScope
))

let dep = try result.target(for: "t1").swiftTarget().compileArguments()
XCTAssertMatch(dep, [.anySequence, "-DDEP", .anySequence])

let cbar = try result.target(for: "cbar").clangTarget().basicArguments(isCXX: false)
XCTAssertMatch(cbar, [.anySequence, "-DCCC=2", "-I\(A.appending(components: "Sources", "cbar", "Sources", "headers"))", "-I\(A.appending(components: "Sources", "cbar", "Sources", "cppheaders"))", "-Icfoo", "-L", "cbar", "-Icxxfoo", "-L", "cxxbar", "-fno-omit-frame-pointer", .end])

let bar = try result.target(for: "bar").swiftTarget().compileArguments()
XCTAssertMatch(bar, [.anySequence, "-DLINUX", "-Isfoo", "-L", "sbar", "-cxx-interoperability-mode=default", "-enable-upcoming-feature", "BestFeature", "-Xcc", "-fno-omit-frame-pointer", .end])

let exe = try result.target(for: "exe").swiftTarget().compileArguments()
XCTAssertMatch(exe, [.anySequence, "-DFOO", "-Xcc", "-fno-omit-frame-pointer", .end])
}

do {
let result = try createResult(for: .macOS)

Expand Down
4 changes: 3 additions & 1 deletion Tests/BuildTests/MockBuildTestHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ func mockBuildParameters(
destinationTriple: Basics.Triple = hostTriple,
indexStoreMode: BuildParameters.IndexStoreMode = .off,
useExplicitModuleBuild: Bool = false,
linkerDeadStrip: Bool = true
linkerDeadStrip: Bool = true,
omitFramePointers: Bool? = nil
) -> BuildParameters {
return try! BuildParameters(
dataPath: buildPath,
Expand All @@ -91,6 +92,7 @@ func mockBuildParameters(
canRenameEntrypointFunctionName: canRenameEntrypointFunctionName,
indexStoreMode: indexStoreMode,
useExplicitModuleBuild: useExplicitModuleBuild,
omitFramePointers: omitFramePointers,
linkerDeadStrip: linkerDeadStrip
)
}
Expand Down

0 comments on commit ef57d9f

Please sign in to comment.