Files
garble/testdata/script/cgo.txtar
Daniel Martí b5d90cb1bd expose cgo issue 916
Seems to happen when the main package only has Go files importing "C",
meaning that it has zero "pure Go" files.

To avoid needing two main package Go builds for cgo.txtar,
switch our main package to this scenario as it seems more interesting.

While here, add a test case for a Go callback function taking a C param
as that is relatively common and we had no coverage for it.

This only reproduces the bug; the fix is coming separately.

For #916.
2025-04-21 07:41:15 +02:00

140 lines
2.5 KiB
Plaintext

[!cgo] skip 'this test requires cgo to be enabled'
! exec garble build
stderr 'cannot define new methods on non-local type _trieNode'
stop
! stderr 'warning' # check that the C toolchain is happy
exec ./main
cmp stdout main.stdout
! binsubstr main$exe 'PortedField' 'test/main'
[short] stop # no need to verify this with -short
# Ensure that reversing works with cgo.
env GARBLE_TEST_REVERSING=true
exec ./main
cp stdout reversing.stdout
stdin reversing.stdout
exec garble reverse .
cmp stdout reversed.stdout
env GARBLE_TEST_REVERSING=false
exec garble -tiny build
exec ./main
cmp stdout main.stdout
go build
! stderr 'warning' # check that the C toolchain is happy
exec ./main
cmp stdout main.stdout
binsubstr main$exe 'privateAdd'
-- go.mod --
module test/main
go 1.23
-- main.go --
package main
// It's important that the main package only has files importing "C",
// as that used to trigger https://github.com/burrowers/garble/issues/916.
import "C"
import "test/main/imported"
func main() {
imported.RegularFunc()
cgoFunc()
}
-- imported/imported_regular.go --
package imported
import (
"fmt"
"os"
"runtime"
)
func RegularFunc() {
if os.Getenv("GARBLE_TEST_REVERSING") == "true" {
_, filename, _, _ := runtime.Caller(0)
fmt.Println("regular filename:", filename)
}
}
-- cgo_main.go --
package main
import (
"fmt"
"os"
"os/user"
"runtime"
)
/*
#include "separate.h" // inline comment
static int privateAdd(int a, int b) {
return a + b;
}
extern void goCallback();
static void callGoCallbacks() {
goCallback();
separateFunction();
}
struct portedStruct {
char* PortedField;
};
*/
import "C"
func cgoFunc() {
fmt.Println(C.privateAdd(C.int(1), C.int(2)))
_, _ = user.Current()
st := C.struct_portedStruct{}
fmt.Println(st.PortedField == nil)
C.callGoCallbacks()
}
//export goCallback
func goCallback() {
fmt.Println("go callback")
// TODO: support reversing filenames in cgo files
if false && os.Getenv("GARBLE_TEST_REVERSING") == "true" {
_, filename, _, _ := runtime.Caller(0)
fmt.Println("cgo filename:", filename)
}
}
//export printString
func printString(cs *C.char) {
fmt.Println(C.GoString(cs))
}
-- separate.h --
void separateFunction();
-- separate.c --
#include "_cgo_export.h"
#include <stdio.h>
void separateFunction() {
goCallback();
printString("string from C");
}
-- main.stdout --
3
true
go callback
go callback
string from C
-- reversed.stdout --
regular filename: test/main/imported/imported_regular.go
3
true
go callback
go callback
string from C