detached bfe9e39

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 Unverified4AEE18F83AFDEB23 The key is unknown
4 files · +52 -5
M callback_test.go +1 -1
@@ -31,7 +31,7 @@ func TestCallGoFromSharedLib(t *testing.T) {
3131
3232 lib, err := purego.Dlopen(libFileName, purego.RTLD_NOW|purego.RTLD_GLOBAL)
3333 if err != nil {
34- t.Fatalf("Dlopen(%q) faled: %v", libFileName, err)
34+ t.Fatalf("Dlopen(%q) failed: %v", libFileName, err)
3535 }
3636
3737 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) int37 var callCallback func(p uintptr, s string) int
M dlfcn.go +4 -4
@@ -35,8 +35,8 @@ func init() {
3535 // Dlopen calls should be balanced with a Dlclose call.
3636 func Dlopen(path string, mode int) (uintptr, error) {
3737 u := fnDlopen(path, mode)
38- if errStr := fnDlerror(); errStr != "" {
39- return 0, Dlerror{errStr}
38+ if u == 0 {
39+ return 0, Dlerror{fnDlerror()}
4040 }
4141 return u, nil
4242 }
@@ -47,8 +47,8 @@ func Dlopen(path string, mode int) (uintptr, error) {
4747 // when that library was loaded, Dlsym returns zero.
4848 func Dlsym(handle uintptr, name string) (uintptr, error) {
4949 u := fnDlsym(handle, name)
50- if errStr := fnDlerror(); errStr != "" {
51- return 0, Dlerror{errStr}
50+ if u == 0 {
51+ return 0, Dlerror{fnDlerror()}
5252 }
5353 return u, nil
5454 }
@@ -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, nil41 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, nil53 return u, nil
54 }54 }
M dlfcn_test.go +33 -0
@@ -7,7 +7,11 @@ package purego_test
77
88 import (
99 "fmt"
10+ "os"
11+ "os/exec"
12+ "path/filepath"
1013 "runtime"
14+ "strings"
1115 "testing"
1216 "unsafe"
1317
@@ -90,3 +94,32 @@ func Test_qsort(t *testing.T) {
9094 }
9195 }
9296 }
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;

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 102

↑↓ moveenter openesc close