From 758eca1984096959099ae7b54889b0fabfeb83c2 Mon Sep 17 00:00:00 2001 From: problematicconsumer Date: Sat, 14 Oct 2023 17:22:26 +0330 Subject: [PATCH] Add panic recover to ffi --- custom/custom.go | 42 +++++++++++++++++++++++++++++++++++------- shared/debug.go | 9 +++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/custom/custom.go b/custom/custom.go index 3f67550..da11f39 100644 --- a/custom/custom.go +++ b/custom/custom.go @@ -30,7 +30,11 @@ func setup(baseDir *C.char, workingDir *C.char, tempDir *C.char, statusPort C.lo } //export parse -func parse(path *C.char, tempPath *C.char, debug bool) *C.char { +func parse(path *C.char, tempPath *C.char, debug bool) (CErr *C.char) { + defer shared.DeferPanicToError("parse", func(err error) { + CErr = C.CString(err.Error()) + }) + err := shared.ParseConfig(C.GoString(path), C.GoString(tempPath), debug) if err != nil { return C.CString(err.Error()) @@ -39,7 +43,11 @@ func parse(path *C.char, tempPath *C.char, debug bool) *C.char { } //export changeConfigOptions -func changeConfigOptions(configOptionsJson *C.char) *C.char { +func changeConfigOptions(configOptionsJson *C.char) (CErr *C.char) { + defer shared.DeferPanicToError("changeConfigOptions", func(err error) { + CErr = C.CString(err.Error()) + }) + configOptions = &shared.ConfigOptions{} err := json.Unmarshal([]byte(C.GoString(configOptionsJson)), configOptions) if err != nil { @@ -49,7 +57,11 @@ func changeConfigOptions(configOptionsJson *C.char) *C.char { } //export start -func start(configPath *C.char) *C.char { +func start(configPath *C.char) (CErr *C.char) { + defer shared.DeferPanicToError("start", func(err error) { + CErr = C.CString(err.Error()) + }) + if status != Stopped { return C.CString("") } @@ -98,7 +110,11 @@ func startService() error { } //export stop -func stop() *C.char { +func stop() (CErr *C.char) { + defer shared.DeferPanicToError("stop", func(err error) { + CErr = C.CString(err.Error()) + }) + if status != Started { return C.CString("") } @@ -125,7 +141,11 @@ func stop() *C.char { } //export restart -func restart(configPath *C.char) *C.char { +func restart(configPath *C.char) (CErr *C.char) { + defer shared.DeferPanicToError("restart", func(err error) { + CErr = C.CString(err.Error()) + }) + if status != Started { return C.CString("") } @@ -164,7 +184,11 @@ func stopCommandClient(command C.int) *C.char { } //export selectOutbound -func selectOutbound(groupTag *C.char, outboundTag *C.char) *C.char { +func selectOutbound(groupTag *C.char, outboundTag *C.char) (CErr *C.char) { + defer shared.DeferPanicToError("selectOutbound", func(err error) { + CErr = C.CString(err.Error()) + }) + err := libbox.NewStandaloneCommandClient().SelectOutbound(C.GoString(groupTag), C.GoString(outboundTag)) if err != nil { return C.CString(err.Error()) @@ -173,7 +197,11 @@ func selectOutbound(groupTag *C.char, outboundTag *C.char) *C.char { } //export urlTest -func urlTest(groupTag *C.char) *C.char { +func urlTest(groupTag *C.char) (CErr *C.char) { + defer shared.DeferPanicToError("urlTest", func(err error) { + CErr = C.CString(err.Error()) + }) + err := libbox.NewStandaloneCommandClient().URLTest(C.GoString(groupTag)) if err != nil { return C.CString(err.Error()) diff --git a/shared/debug.go b/shared/debug.go index 683a738..e95041a 100644 --- a/shared/debug.go +++ b/shared/debug.go @@ -3,8 +3,10 @@ package shared import ( "bytes" "encoding/json" + "fmt" "os" "path/filepath" + "runtime/debug" "github.com/sagernet/sing-box/option" ) @@ -20,3 +22,10 @@ func SaveCurrentConfig(path string, options option.Options) error { } return os.WriteFile(filepath.Join(path, "current-config.json"), buffer.Bytes(), 0777) } + +func DeferPanicToError(name string, err func(error)) { + if r := recover(); r != nil { + s := fmt.Errorf("%s panic: %s\n%s", name, r, string(debug.Stack())) + err(s) + } +}