codegen: Use the new frame-pointer fn attributes

no-frame-pointer-elim and no-frame-pointer-elim-non-leaf have been
deprecated for a while in favour of the newer (and clearer)
frame-pointer attribute.

Starting with LLVM10 the old attributes are silently ignored, leading to
no stack traces in debug mode.
This commit is contained in:
LemonBoy 2020-02-07 17:08:21 +01:00
parent 5076f2d4f6
commit 8d6536b50c
2 changed files with 95 additions and 53 deletions

View file

@ -564,8 +564,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
add_uwtable_attr(g, llvm_fn); add_uwtable_attr(g, llvm_fn);
addLLVMFnAttr(llvm_fn, "nobuiltin"); addLLVMFnAttr(llvm_fn, "nobuiltin");
if (codegen_have_frame_pointer(g) && fn->fn_inline != FnInlineAlways) { if (codegen_have_frame_pointer(g) && fn->fn_inline != FnInlineAlways) {
ZigLLVMAddFunctionAttr(llvm_fn, "no-frame-pointer-elim", "true"); ZigLLVMAddFunctionAttr(llvm_fn, "frame-pointer", "all");
ZigLLVMAddFunctionAttr(llvm_fn, "no-frame-pointer-elim-non-leaf", nullptr);
} }
if (fn->section_name) { if (fn->section_name) {
LLVMSetSection(llvm_fn, buf_ptr(fn->section_name)); LLVMSetSection(llvm_fn, buf_ptr(fn->section_name));
@ -1128,8 +1127,7 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {
// on any architecture. // on any architecture.
addLLVMArgAttr(fn_val, (unsigned)0, "nonnull"); addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");
if (codegen_have_frame_pointer(g)) { if (codegen_have_frame_pointer(g)) {
ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true"); ZigLLVMAddFunctionAttr(fn_val, "frame-pointer", "all");
ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr);
} }
LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry"); LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry");
@ -1206,8 +1204,7 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
addLLVMFnAttr(fn_val, "nounwind"); addLLVMFnAttr(fn_val, "nounwind");
add_uwtable_attr(g, fn_val); add_uwtable_attr(g, fn_val);
if (codegen_have_frame_pointer(g)) { if (codegen_have_frame_pointer(g)) {
ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true"); ZigLLVMAddFunctionAttr(fn_val, "frame-pointer", "all");
ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr);
} }
// this is above the ZigLLVMClearCurrentDebugLocation // this is above the ZigLLVMClearCurrentDebugLocation
@ -1290,8 +1287,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
addLLVMFnAttr(fn_val, "nounwind"); addLLVMFnAttr(fn_val, "nounwind");
add_uwtable_attr(g, fn_val); add_uwtable_attr(g, fn_val);
if (codegen_have_frame_pointer(g)) { if (codegen_have_frame_pointer(g)) {
ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true"); ZigLLVMAddFunctionAttr(fn_val, "frame-pointer", "all");
ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr);
} }
// Not setting alignment here. See the comment above about // Not setting alignment here. See the comment above about
// "Cannot getTypeInfo() on a type that is unsized!" // "Cannot getTypeInfo() on a type that is unsized!"
@ -4995,8 +4991,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {
addLLVMFnAttr(fn_val, "nounwind"); addLLVMFnAttr(fn_val, "nounwind");
add_uwtable_attr(g, fn_val); add_uwtable_attr(g, fn_val);
if (codegen_have_frame_pointer(g)) { if (codegen_have_frame_pointer(g)) {
ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true"); ZigLLVMAddFunctionAttr(fn_val, "frame-pointer", "all");
ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr);
} }
LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder); LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder);

View file

@ -41,6 +41,21 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
\\ try foo(); \\ try foo();
\\} \\}
; ;
const source_dumpCurrentStackTrace =
\\const std = @import("std");
\\
\\fn bar() void {
\\ std.debug.dumpCurrentStackTrace(@returnAddress());
\\}
\\fn foo() void {
\\ bar();
\\}
\\pub fn main() u8 {
\\ foo();
\\ return 1;
\\}
;
// zig fmt: off // zig fmt: off
switch (builtin.os) { switch (builtin.os) {
.freebsd => { .freebsd => {
@ -256,6 +271,38 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
\\ \\
}, },
); );
cases.addCase(
"dumpCurrentStackTrace",
source_dumpCurrentStackTrace,
[_][]const u8{
// debug
\\source.zig:7:8: [address] in foo (test)
\\ bar();
\\ ^
\\source.zig:10:8: [address] in main (test)
\\ foo();
\\ ^
\\start.zig:247:29: [address] in std.start.posixCallMainAndExit (test)
\\ return root.main();
\\ ^
\\start.zig:114:5: [address] in std.start._start (test)
\\ @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
\\ ^
\\
,
// release-safe
\\start.zig:114:5: [address] in std.start._start (test)
\\ @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
\\ ^
\\
,
// release-fast
\\
,
// release-small
\\
},
);
}, },
.macosx => { .macosx => {
cases.addCase( cases.addCase(