Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement segfault handler in Crystal #10463

Merged
merged 6 commits into from
Apr 8, 2021
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
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,3 @@ all_spec
/src/llvm/ext/llvm_ext.o
/src/llvm/ext/llvm_ext.obj
/src/llvm/ext/llvm_ext.dwo
/src/ext/*.o
/src/ext/libcrystal.a
2 changes: 0 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,6 @@ Additionally, all official documentation can be found on [the Crystal website](h
1. Fork it ( https://github.com/crystal-lang/crystal/fork )
2. Clone it

Be sure to execute `make libcrystal` inside the cloned repository.

Once in the cloned directory, and once you [installed Crystal](https://crystal-lang.org/install/),
you can execute `bin/crystal` instead of `crystal`. This is a wrapper that will use the cloned repository
as the standard library. Otherwise the barebones `crystal` executable uses the standard library that comes in
Expand Down
14 changes: 2 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,7 @@ SHELL = sh
LLVM_CONFIG := $(shell src/llvm/ext/find-llvm-config)
LLVM_EXT_DIR = src/llvm/ext
LLVM_EXT_OBJ = $(LLVM_EXT_DIR)/llvm_ext.o
LIB_CRYSTAL_SOURCES = $(shell find src/ext -name '*.c')
LIB_CRYSTAL_OBJS = $(subst .c,.o,$(LIB_CRYSTAL_SOURCES))
LIB_CRYSTAL_TARGET = src/ext/libcrystal.a
DEPS = $(LLVM_EXT_OBJ) $(LIB_CRYSTAL_TARGET)
CFLAGS += -fPIC $(if $(debug),-g -O0)
DEPS = $(LLVM_EXT_OBJ)
CXXFLAGS += $(if $(debug),-g -O0)
CRYSTAL_VERSION ?= $(shell cat src/VERSION)

Expand Down Expand Up @@ -99,11 +95,9 @@ docs: ## Generate standard library documentation
.PHONY: crystal
crystal: $(O)/crystal ## Build the compiler

.PHONY: deps llvm_ext libcrystal
.PHONY: deps llvm_ext
deps: $(DEPS) ## Build dependencies

llvm_ext: $(LLVM_EXT_OBJ)
libcrystal: $(LIB_CRYSTAL_TARGET)

$(O)/all_spec: $(DEPS) $(SOURCES) $(SPEC_SOURCES)
@mkdir -p $(O)
Expand All @@ -124,13 +118,9 @@ $(O)/crystal: $(DEPS) $(SOURCES)
$(LLVM_EXT_OBJ): $(LLVM_EXT_DIR)/llvm_ext.cc
$(CXX) -c $(CXXFLAGS) -o $@ $< $(shell $(LLVM_CONFIG) --cxxflags)

$(LIB_CRYSTAL_TARGET): $(LIB_CRYSTAL_OBJS)
$(AR) -rcs $@ $^

.PHONY: clean
clean: clean_crystal ## Clean up built directories and files
rm -rf $(LLVM_EXT_OBJ)
rm -rf $(LIB_CRYSTAL_OBJS) $(LIB_CRYSTAL_TARGET)

.PHONY: clean_crystal
clean_crystal: ## Clean up crystal built files
Expand Down
1 change: 0 additions & 1 deletion shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,5 @@ pkgs.stdenv.mkDerivation rec {

LLVM_CONFIG = "${llvm_suite.llvm}/bin/llvm-config";

# ld: warning: object file (.../src/ext/libcrystal.a(sigfault.o)) was built for newer OSX version (10.14) than being linked (10.12)
MACOSX_DEPLOYMENT_TARGET = "10.11";
}
4 changes: 0 additions & 4 deletions src/ext.cr

This file was deleted.

27 changes: 0 additions & 27 deletions src/ext/sigfault.c

This file was deleted.

4 changes: 2 additions & 2 deletions src/kernel.cr
Original file line number Diff line number Diff line change
Expand Up @@ -535,12 +535,12 @@ end
end

Signal.setup_default_handlers
LibExt.setup_sigfault_handler
Signal.setup_segfault_handler
{% end %}

{% if !flag?(:win32) %}
# load dwarf on start up of the program is executed with CRYSTAL_LOAD_DWARF=1
# this will make dwarf available on print_frame that is used on __crystal_sigfault_handler
# this will make dwarf available on print_frame that is used by Crystal's segfault handler
#
# - CRYSTAL_LOAD_DWARF=0 will never use dwarf information (See Exception::CallStack.load_dwarf)
# - CRYSTAL_LOAD_DWARF=1 will load dwarf on startup
Expand Down
34 changes: 34 additions & 0 deletions src/lib_c/aarch64-darwin/c/signal.cr
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ lib LibC
SIGINFO = 29
SIGWINCH = 28

SIGSTKSZ = 131072

SIG_SETMASK = 3

alias SighandlerT = Int ->
Expand All @@ -42,9 +44,41 @@ lib LibC
SIG_DFL = SighandlerT.new(Pointer(Void).new(0_u64), Pointer(Void).null)
SIG_IGN = SighandlerT.new(Pointer(Void).new(1_u64), Pointer(Void).null)

SA_ONSTACK = 0x0001
SA_SIGINFO = 0x0040

struct SiginfoT
si_signo : Int
si_errno : Int
si_code : Int
si_pid : PidT
si_uid : UidT
si_status : Int
si_addr : Void*
_pad : StaticArray(SizeT, 9)
end

alias SigactionHandlerT = (Int, SiginfoT*, Void*) ->

struct Sigaction
# Technically a union, but only one can be valid and we only use sa_sigaction
# and not sa_handler (which would be a SighandlerT)
sa_sigaction : SigactionHandlerT
sa_mask : SigsetT
sa_flags : Int
end

struct StackT
ss_sp : Void*
ss_size : SizeT
ss_flags : Int
end

fun kill(x0 : PidT, x1 : Int) : Int
fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int
fun signal(x0 : Int, x1 : Int -> Void) : Int -> Void
fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int
fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int
fun sigemptyset(SigsetT*) : Int
fun sigfillset(SigsetT*) : Int
fun sigaddset(SigsetT*, Int) : Int
Expand Down
33 changes: 32 additions & 1 deletion src/lib_c/aarch64-linux-gnu/c/signal.cr
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,50 @@ lib LibC
SIGSTKFLT = 16
SIGUNUSED = 31

SIGSTKSZ = 16384

SIG_SETMASK = 2

alias SighandlerT = Int ->
SIG_DFL = SighandlerT.new(Pointer(Void).new(0_u64), Pointer(Void).null)
SIG_IGN = SighandlerT.new(Pointer(Void).new(1_u64), Pointer(Void).null)

struct SigsetT
val : ULong[32] # (1024 / (8 * sizeof(long)))
val : ULong[16] # (1024 / (8 * sizeof(ULong)))
end

SA_ONSTACK = 0x08000000
SA_SIGINFO = 0x00000004

struct SiginfoT
si_signo : Int
si_errno : Int
si_code : Int
__pad0 : Int
si_addr : Void* # Assuming the sigfault form of siginfo_t
__pad1 : StaticArray(Int, 20) # __SI_PAD_SIZE (28) - sizeof(void*) (8) = 20
end

alias SigactionHandlerT = (Int, SiginfoT*, Void*) ->

struct Sigaction
sa_sigaction : SigactionHandlerT
sa_mask : SigsetT
sa_flags : Int
sa_restorer : Void*
end

struct StackT
ss_sp : Void*
ss_flags : Int
ss_size : SizeT
end

fun kill(pid : PidT, sig : Int) : Int
fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int
fun signal(sig : Int, handler : Int -> Void) : Int -> Void
fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int
fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int
fun sigemptyset(SigsetT*) : Int
fun sigfillset(SigsetT*) : Int
fun sigaddset(SigsetT*, Int) : Int
Expand Down
31 changes: 31 additions & 0 deletions src/lib_c/aarch64-linux-musl/c/signal.cr
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ lib LibC
SIGSTKFLT = 16
SIGUNUSED = LibC::SIGSYS

SIGSTKSZ = 12288

SIG_SETMASK = 2

alias SighandlerT = Int ->
Expand All @@ -45,9 +47,38 @@ lib LibC
val : ULong[16] # 128 / sizeof(long)
end

SA_ONSTACK = 0x08000000
SA_SIGINFO = 0x00000004

struct SiginfoT
si_signo : Int
si_errno : Int
si_code : Int
__pad0 : Int
si_addr : Void* # Assuming the sigfault form of siginfo_t
__pad1 : StaticArray(Int, 20) # __SI_PAD_SIZE (28) - sizeof(void*) (8) = 20
end

alias SigactionHandlerT = (Int, SiginfoT*, Void*) ->

struct Sigaction
sa_sigaction : SigactionHandlerT
sa_mask : SigsetT
sa_flags : Int
sa_restorer : Void*
end

struct StackT
ss_sp : Void*
ss_flags : Int
ss_size : SizeT
end

fun kill(x0 : PidT, x1 : Int) : Int
fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int
fun signal(x0 : Int, x1 : Int -> Void) : Int -> Void
fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int
fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int
fun sigemptyset(SigsetT*) : Int
fun sigfillset(SigsetT*) : Int
fun sigaddset(SigsetT*, Int) : Int
Expand Down
30 changes: 30 additions & 0 deletions src/lib_c/arm-linux-gnueabihf/c/signal.cr
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ lib LibC
SIGSTKFLT = 16
SIGUNUSED = 31

SIGSTKSZ = 8192

SIG_SETMASK = 2

alias SighandlerT = Int ->
Expand All @@ -46,9 +48,37 @@ lib LibC
val : ULong[32] # (1024 / (8 * sizeof(long)))
end

SA_ONSTACK = 0x08000000
SA_SIGINFO = 0x00000004

struct SiginfoT
si_signo : Int
si_errno : Int
si_code : Int
si_addr : Void* # Assuming the sigfault form of siginfo_t
__pad : StaticArray(Int, 25) # __SI_PAD_SIZE (29) - sizeof(void*) (4) = 25
end

alias SigactionHandlerT = (Int, SiginfoT*, Void*) ->

struct Sigaction
sa_sigaction : SigactionHandlerT
sa_mask : SigsetT
sa_flags : Int
sa_restorer : Void*
end

struct StackT
ss_sp : Void*
ss_flags : Int
ss_size : SizeT
end

fun kill(pid : PidT, sig : Int) : Int
fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int
fun signal(sig : Int, handler : Int -> Void) : Int -> Void
fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int
fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int
fun sigemptyset(SigsetT*) : Int
fun sigfillset(SigsetT*) : Int
fun sigaddset(SigsetT*, Int) : Int
Expand Down
30 changes: 30 additions & 0 deletions src/lib_c/i386-linux-gnu/c/signal.cr
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ lib LibC
SIGSTKFLT = 16
SIGUNUSED = 31

SIGSTKSZ = 8192

SIG_SETMASK = 2

alias SighandlerT = Int ->
Expand All @@ -46,9 +48,37 @@ lib LibC
val : ULong[32] # (1024 / (8 * sizeof(long)))
end

SA_ONSTACK = 0x08000000
SA_SIGINFO = 0x00000004

struct SiginfoT
si_signo : Int
si_errno : Int
si_code : Int
si_addr : Void* # Assuming the sigfault form of siginfo_t
__pad : StaticArray(Int, 25) # __SI_PAD_SIZE (29) - sizeof(void*) (4) = 25
end

alias SigactionHandlerT = (Int, SiginfoT*, Void*) ->

struct Sigaction
sa_sigaction : SigactionHandlerT
sa_mask : SigsetT
sa_flags : Int
sa_restorer : Void*
end

struct StackT
ss_sp : Void*
ss_flags : Int
ss_size : SizeT
end

fun kill(pid : PidT, sig : Int) : Int
fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int
fun signal(sig : Int, handler : Int -> Void) : Int -> Void
fun sigaction(x0 : Int, x1 : Sigaction*, x2 : Sigaction*) : Int
fun sigaltstack(x0 : StackT*, x1 : StackT*) : Int
fun sigemptyset(SigsetT*) : Int
fun sigfillset(SigsetT*) : Int
fun sigaddset(SigsetT*, Int) : Int
Expand Down
Loading