dlfcn: rework error check (#119)
Closes #118 Signed-off-by: Eliott Bouhana <eliott.bouhana@datadoghq.fr> Co-authored-by: Eliott Bouhana <eliott.bouhana@datadoghq.fr>
- commit
- bfe9e39de4ceb9145dbe879a6b1d4900b102c211
- author
- Eliott Bouhana · · 2023-03-30 15:15 UTC
- committer
- GitHub · · 2023-03-30 15:15 UTC
- parent
- ebd8567
- signature
- GPG Unverified
4AEE18F83AFDEB23The key is unknown
4 files · +52 -5
M callback_test.go +1 -1
| @@ -31,7 +31,7 @@ func TestCallGoFromSharedLib(t *testing.T) { | |||
| 31 | 31 | ||
| 32 | 32 | lib, err := purego.Dlopen(libFileName, purego.RTLD_NOW|purego.RTLD_GLOBAL) | |
| 33 | 33 | if err != nil { | |
| 34 | - | t.Fatalf("Dlopen(%q) faled: %v", libFileName, err) | |
| 34 | + | t.Fatalf("Dlopen(%q) failed: %v", libFileName, err) | |
| 35 | 35 | } | |
| 36 | 36 | ||
| 37 | 37 | var callCallback func(p uintptr, s string) int | |
| @@ -31,7 +31,7 @@ func TestCallGoFromSharedLib(t *testing.T) { | |||||
| 31 | 31 | ||||
| 32 | lib, err := purego.Dlopen(libFileName, purego.RTLD_NOW|purego.RTLD_GLOBAL) | 32 | lib, err := purego.Dlopen(libFileName, purego.RTLD_NOW|purego.RTLD_GLOBAL) | ||
| 33 | if err != nil { | 33 | if err != nil { | ||
| 34 | - | t.Fatalf("Dlopen(%q) faled: %v", libFileName, err) | 34 | + | t.Fatalf("Dlopen(%q) failed: %v", libFileName, err) |
| 35 | } | 35 | } | ||
| 36 | 36 | ||||
| 37 | var callCallback func(p uintptr, s string) int | 37 | var callCallback func(p uintptr, s string) int | ||
M dlfcn.go +4 -4
| @@ -35,8 +35,8 @@ func init() { | |||
| 35 | 35 | // Dlopen calls should be balanced with a Dlclose call. | |
| 36 | 36 | func Dlopen(path string, mode int) (uintptr, error) { | |
| 37 | 37 | u := fnDlopen(path, mode) | |
| 38 | - | if errStr := fnDlerror(); errStr != "" { | |
| 39 | - | return 0, Dlerror{errStr} | |
| 38 | + | if u == 0 { | |
| 39 | + | return 0, Dlerror{fnDlerror()} | |
| 40 | 40 | } | |
| 41 | 41 | return u, nil | |
| 42 | 42 | } | |
| @@ -47,8 +47,8 @@ func Dlopen(path string, mode int) (uintptr, error) { | |||
| 47 | 47 | // when that library was loaded, Dlsym returns zero. | |
| 48 | 48 | func Dlsym(handle uintptr, name string) (uintptr, error) { | |
| 49 | 49 | u := fnDlsym(handle, name) | |
| 50 | - | if errStr := fnDlerror(); errStr != "" { | |
| 51 | - | return 0, Dlerror{errStr} | |
| 50 | + | if u == 0 { | |
| 51 | + | return 0, Dlerror{fnDlerror()} | |
| 52 | 52 | } | |
| 53 | 53 | return u, nil | |
| 54 | 54 | } | |
| @@ -35,8 +35,8 @@ func init() { | |||||
| 35 | // Dlopen calls should be balanced with a Dlclose call. | 35 | // Dlopen calls should be balanced with a Dlclose call. | ||
| 36 | func Dlopen(path string, mode int) (uintptr, error) { | 36 | func Dlopen(path string, mode int) (uintptr, error) { | ||
| 37 | u := fnDlopen(path, mode) | 37 | u := fnDlopen(path, mode) | ||
| 38 | - | if errStr := fnDlerror(); errStr != "" { | 38 | + | if u == 0 { |
| 39 | - | return 0, Dlerror{errStr} | 39 | + | return 0, Dlerror{fnDlerror()} |
| 40 | } | 40 | } | ||
| 41 | return u, nil | 41 | return u, nil | ||
| 42 | } | 42 | } | ||
| @@ -47,8 +47,8 @@ func Dlopen(path string, mode int) (uintptr, error) { | |||||
| 47 | // when that library was loaded, Dlsym returns zero. | 47 | // when that library was loaded, Dlsym returns zero. | ||
| 48 | func Dlsym(handle uintptr, name string) (uintptr, error) { | 48 | func Dlsym(handle uintptr, name string) (uintptr, error) { | ||
| 49 | u := fnDlsym(handle, name) | 49 | u := fnDlsym(handle, name) | ||
| 50 | - | if errStr := fnDlerror(); errStr != "" { | 50 | + | if u == 0 { |
| 51 | - | return 0, Dlerror{errStr} | 51 | + | return 0, Dlerror{fnDlerror()} |
| 52 | } | 52 | } | ||
| 53 | return u, nil | 53 | return u, nil | ||
| 54 | } | 54 | } | ||
M dlfcn_test.go +33 -0
| @@ -7,7 +7,11 @@ package purego_test | |||
| 7 | 7 | ||
| 8 | 8 | import ( | |
| 9 | 9 | "fmt" | |
| 10 | + | "os" | |
| 11 | + | "os/exec" | |
| 12 | + | "path/filepath" | |
| 10 | 13 | "runtime" | |
| 14 | + | "strings" | |
| 11 | 15 | "testing" | |
| 12 | 16 | "unsafe" | |
| 13 | 17 | ||
| @@ -90,3 +94,32 @@ func Test_qsort(t *testing.T) { | |||
| 90 | 94 | } | |
| 91 | 95 | } | |
| 92 | 96 | } | |
| 97 | + | ||
| 98 | + | func TestNestedDlopenCall(t *testing.T) { | |
| 99 | + | libFileName := filepath.Join(t.TempDir(), "libdlnested.so") | |
| 100 | + | t.Logf("Build %v", libFileName) | |
| 101 | + | ||
| 102 | + | out, err := exec.Command("go", "env", "CXX").Output() | |
| 103 | + | if err != nil { | |
| 104 | + | t.Fatalf("go env error: %v", err) | |
| 105 | + | } | |
| 106 | + | ||
| 107 | + | cxx := strings.TrimSpace(string(out)) | |
| 108 | + | if cxx == "" { | |
| 109 | + | t.Fatal("CXX not found") | |
| 110 | + | } | |
| 111 | + | ||
| 112 | + | args := []string{"-shared", "-Wall", "-Werror", "-o", libFileName, filepath.Join("libdlnested", "nested.cpp")} | |
| 113 | + | cmd := exec.Command(cxx, args...) | |
| 114 | + | if out, err := cmd.CombinedOutput(); err != nil { | |
| 115 | + | t.Fatalf("compile lib: %v\n%q\n%s", err, cmd, string(out)) | |
| 116 | + | } | |
| 117 | + | defer os.Remove(libFileName) | |
| 118 | + | ||
| 119 | + | lib, err := purego.Dlopen(libFileName, purego.RTLD_NOW|purego.RTLD_GLOBAL) | |
| 120 | + | if err != nil { | |
| 121 | + | t.Fatalf("Dlopen(%q) failed: %v", libFileName, err) | |
| 122 | + | } | |
| 123 | + | ||
| 124 | + | purego.Dlclose(lib) | |
| 125 | + | } | |
| @@ -7,7 +7,11 @@ package purego_test | |||||
| 7 | 7 | ||||
| 8 | import ( | 8 | import ( | ||
| 9 | "fmt" | 9 | "fmt" | ||
| 10 | + | "os" | |||
| 11 | + | "os/exec" | |||
| 12 | + | "path/filepath" | |||
| 10 | "runtime" | 13 | "runtime" | ||
| 14 | + | "strings" | |||
| 11 | "testing" | 15 | "testing" | ||
| 12 | "unsafe" | 16 | "unsafe" | ||
| 13 | 17 | ||||
| @@ -90,3 +94,32 @@ func Test_qsort(t *testing.T) { | |||||
| 90 | } | 94 | } | ||
| 91 | } | 95 | } | ||
| 92 | } | 96 | } | ||
| 97 | + | ||||
| 98 | + | func TestNestedDlopenCall(t *testing.T) { | |||
| 99 | + | libFileName := filepath.Join(t.TempDir(), "libdlnested.so") | |||
| 100 | + | t.Logf("Build %v", libFileName) | |||
| 101 | + | ||||
| 102 | + | out, err := exec.Command("go", "env", "CXX").Output() | |||
| 103 | + | if err != nil { | |||
| 104 | + | t.Fatalf("go env error: %v", err) | |||
| 105 | + | } | |||
| 106 | + | ||||
| 107 | + | cxx := strings.TrimSpace(string(out)) | |||
| 108 | + | if cxx == "" { | |||
| 109 | + | t.Fatal("CXX not found") | |||
| 110 | + | } | |||
| 111 | + | ||||
| 112 | + | args := []string{"-shared", "-Wall", "-Werror", "-o", libFileName, filepath.Join("libdlnested", "nested.cpp")} | |||
| 113 | + | cmd := exec.Command(cxx, args...) | |||
| 114 | + | if out, err := cmd.CombinedOutput(); err != nil { | |||
| 115 | + | t.Fatalf("compile lib: %v\n%q\n%s", err, cmd, string(out)) | |||
| 116 | + | } | |||
| 117 | + | defer os.Remove(libFileName) | |||
| 118 | + | ||||
| 119 | + | lib, err := purego.Dlopen(libFileName, purego.RTLD_NOW|purego.RTLD_GLOBAL) | |||
| 120 | + | if err != nil { | |||
| 121 | + | t.Fatalf("Dlopen(%q) failed: %v", libFileName, err) | |||
| 122 | + | } | |||
| 123 | + | ||||
| 124 | + | purego.Dlclose(lib) | |||
| 125 | + | } | |||
A libdlnested/nested.cpp +14 -0
| @@ -0,0 +1,14 @@ | |||
| 1 | + | // SPDX-License-Identifier: Apache-2.0 | |
| 2 | + | // SPDX-FileCopyrightText: 2023 The Ebitengine Authors | |
| 3 | + | ||
| 4 | + | #include <dlfcn.h> | |
| 5 | + | ||
| 6 | + | struct nested_libdl | |
| 7 | + | { | |
| 8 | + | nested_libdl() { | |
| 9 | + | // Fails for sure because a symbol cannot be named like this | |
| 10 | + | dlsym(RTLD_DEFAULT, "@/*<>"); | |
| 11 | + | } | |
| 12 | + | }; | |
| 13 | + | ||
| 14 | + | static nested_libdl test; | |
| @@ -0,0 +1,14 @@ | |||||
| 1 | + | // SPDX-License-Identifier: Apache-2.0 | |||
| 2 | + | // SPDX-FileCopyrightText: 2023 The Ebitengine Authors | |||
| 3 | + | ||||
| 4 | + | #include <dlfcn.h> | |||
| 5 | + | ||||
| 6 | + | struct nested_libdl | |||
| 7 | + | { | |||
| 8 | + | nested_libdl() { | |||
| 9 | + | // Fails for sure because a symbol cannot be named like this | |||
| 10 | + | dlsym(RTLD_DEFAULT, "@/*<>"); | |||
| 11 | + | } | |||
| 12 | + | }; | |||
| 13 | + | ||||
| 14 | + | static nested_libdl test; | |||