Getting '[signal SIGSEGV: segmentation violation code=0x1 addr=0xffffffff04d07885 pc=0x7fe62f2d2922]' during cgo_call

989 views
Skip to first unread message

Nitish Saboo

unread,
Feb 17, 2020, 9:33:00 AM2/17/20
to golang-nuts
Hi,

This is my go env:

nsaboo@ubuntu:~$ go version
go version go1.12.4 linux/amd64
nsaboo@ubuntu:~$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/nsaboo/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/nsaboo/Documents/goworkspace"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build659816641=/tmp/go-build -gno-record-gcc-switches"

'go build -v -x main.go' went through fine and the binary(main) was created successfully.

While making a cgo call from go code to C code I am getting the following error:

nsaboo@ubuntu:~/Documents/goworkspace/src/poc$ ./main
GOMAZPROCS : 2
START
DIR: /home/nsaboo/Documents/goworkspace/src/poc
Reached C module path :/usr/local/lib/syslog-ng
Reached C filepath :/home/nsaboo/Documents/goworkspace/src/poc/patterns_test.xml
Printing patterndb address: 0x151e1e0
Just before parsing
fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0xffffffff04d07885 pc=0x7fe62f2d2922]

runtime stack:
runtime.throw(0x4f7e77, 0x2a)
/usr/local/go/src/runtime/panic.go:617 +0x72
runtime.sigpanic()
/usr/local/go/src/runtime/signal_unix.go:374 +0x4a9

goroutine 1 [syscall]:
runtime.cgocall(0x4b7380, 0xc000044d90, 0xc0000a8000)
/usr/local/go/src/runtime/cgocall.go:128 +0x5b fp=0xc000044d60 sp=0xc000044d28 pc=0x404f4b
main._Cfunc_match(0x16e3880, 0x16c, 0x154d680, 0x7)
_cgo_gotypes.go:165 +0x45 fp=0xc000044d90 sp=0xc000044d60 pc=0x4b4825
main.Syslogparser.ParseMessage(0xc0000a4000, 0x3c, 0x4f47dd, 0x18, 0xc0000a6000, 0x0, 0x7, 0x4f915f, 0x16c)
/home/nsaboo/Documents/goworkspace/src/poc/main.go:120 +0x12c fp=0xc000044e10 sp=0xc000044d90 pc=0x4b56ec
main.main()
/home/nsaboo/Documents/goworkspace/src/poc/main.go:219 +0x3c1 fp=0xc000044f98 sp=0xc000044e10 pc=0x4b6031
runtime.main()
/usr/local/go/src/runtime/proc.go:200 +0x20c fp=0xc000044fe0 sp=0xc000044f98 pc=0x42cd7c
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc000044fe8 sp=0xc000044fe0 pc=0x4548a1

1)How can I debug this error further ?

2)What could be the reason for this error ?

Thanks,
Nitish

K.S. Bhaskar

unread,
Feb 17, 2020, 9:44:35 AM2/17/20
to golang-nuts
Chances are that a parameter or structure you are passing from Go to C is getting garbage collected by Go before the C code is done with it. Read the CGO documentaton – it's dense, but every sentence, every word, has a purpose.

In case it helps, take a look at the video of my recent talk at FOSDEM 2020 in Brussels (https://fosdem.org/2020/schedule/event/dragonscgo/); slides at https://docs.yottadb.com/Presentations/200202-1DragonsofCGOFOSDEM.pdf

Regards
– Bhaskar

Nitish Saboo

unread,
Feb 17, 2020, 10:33:42 AM2/17/20
to K.S. Bhaskar, golang-nuts
Hi,

These are my Go and C functions.I cannot explicitly garbage collect the C method before use, not sure if that is the issue.
The first line in the 'match' method itself is not getting printed.

void match(const gchar *x, size_t len_x, const gchar *y, size_t len_y)
{
 printf("Reached match method ");
  LogMessage *msg = log_msg_new_empty();
  log_msg_set_value(msg, LM_V_MESSAGE, x, len_x);
  log_msg_set_value(msg, LM_V_PROGRAM, y, len_y);
  pattern_db_process(db_pattern, msg);
  log_msg_unref(msg);

}

func (obj parser) ParseMessage(x string, y string)
{

  app := C.CString(x)
  defer C.free(unsafe.Pointer(app))
  msg := C.CString(y)
  defer C.free(unsafe.Pointer(msg))
  C.match(msg, C.size_t(len(y)), app, C.size_t(len(x)))
}

Thanks,
Nitish

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/4ce0c9a3-9ed7-4408-9d49-d8b0b2960ea4%40googlegroups.com.

K.S. Bhaskar

unread,
Feb 17, 2020, 10:44:38 AM2/17/20
to golang-nuts
See whether runtime.Keepalive (https://golang.org/pkg/runtime/#KeepAlive) helps.

Regards
– Bhaskar
To unsubscribe from this group and stop receiving emails from it, send an email to golan...@googlegroups.com.

Nitish Saboo

unread,
Feb 17, 2020, 11:20:07 AM2/17/20
to K.S. Bhaskar, golang-nuts
Hi,

How can runtime.Keepalive be helpful here ?

Thanks,
Nitish

To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/225d453d-1f5f-4da1-8b65-d97ba3b404f1%40googlegroups.com.

robert engels

unread,
Feb 17, 2020, 11:41:08 AM2/17/20
to Nitish Saboo, K.S. Bhaskar, golang-nuts
I was curious about that too. Looking at the documentation, the runtime.KeepAlive documentation could be improved:

A very simplified example showing where KeepAlive is required:

type File struct { d int }
d, err := syscall.Open("/file/path", syscall.O_RDONLY, 0)
// ... do something if err != nil ...
p := &File{d}
runtime.SetFinalizer(p, func(p *File) { syscall.Close(p.d) })
var buf [10]byte
n, err := syscall.Read(p.d, buf[:])
// Ensure p is not finalized until Read returns.
runtime.KeepAlive(p)
// No more uses of p after this point.

Without the KeepAlive call, the finalizer could run at the start of syscall.Read, closing the file descriptor before syscall.Read makes the actual system call.

Since runtime.KeepAlive is not really needed here, since the the code could be

if p != nil 

Any usage of p later in the function would keep it alive - the important point of using runtime.KeepAlive would be when Go no longer tracks the object (tracked in CGO for instance) - I don’t think this contrived usage example imparts the correct information.

Back to the point, what the responder was saying, is that your program is crashing dereferencing a pointer that Go has already collected - by using runtime.KeepAlive you can (as a test) keep these pointers alive and see if that fixes your problem - then you know where the problem lies (object lifetimes).



K.S. Bhaskar

unread,
Feb 17, 2020, 11:41:25 AM2/17/20
to golang-nuts
I think you may be right, and I think I was barking up the wrong tree. Sorry.

Regards
– Bhaskar

Tamás Gulácsi

unread,
Feb 17, 2020, 3:31:18 PM2/17/20
to golang-nuts
To unsubscribe from this group and stop receiving emails from it, send an email to golan...@googlegroups.com.


You call "void match(const gchar *x, size_t len_x, const gchar *y, size_t len_y)"
as "C.match(msg, C.size_t(len(y)), app, C.size_t(len(x)))" , where

  app := C.CString(x)
  defer C.free(unsafe.Pointer(app))
  msg := C.CString(y)
  defer C.free(unsafe.Pointer(msg))
?

Are the x, y, app, msg and the length in the correct order?
Does any of the input strings contains '\0' (zero byte) ?

Nitish Saboo

unread,
Feb 18, 2020, 1:51:52 AM2/18/20
to Tamás Gulácsi, golang-nuts
Hi Tamas,

You call "void match(const gchar *x, size_t len_x, const gchar *y, size_t len_y)"
as "C.match(msg, C.size_t(len(y)), app, C.size_t(len(x)))" , where
  app := C.CString(x)
  defer C.free(unsafe.Pointer(app))
  msg := C.CString(y)
  defer C.free(unsafe.Pointer(msg))
?

Are the x, y, app, msg and the length in the correct order?

Yes, x,y, app, msg are in correct order.
Does any of the input strings contains '\0' (zero byte) ?

No, none of the input strings are of zero byte.

Thanks,
Nitish

To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/9567cb52-9735-483a-a916-f41a72e838e1%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages