Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime/cgo: allow external library to register its own signal handler? #4216

Closed
knuesel opened this issue Oct 8, 2012 · 11 comments
Closed

Comments

@knuesel
Copy link

knuesel commented Oct 8, 2012

A call to C.readline() from the GNU Readline library crashes when SIGWINCH is received.

Running the following program:

    package main

    // #cgo LDFLAGS: -lreadline
    // #include <readline/readline.h>
    import "C"

    func main() {
        C.readline(C.CString("> "))
    }

And resizing the terminal gives this panic:

> panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x1c pc=0x7f1a7644a3c5]

goroutine 2 [syscall]:
created by runtime.main
    /home/knuesel/repos/go/src/pkg/runtime/proc.c:221

goroutine 1 [syscall]:
main._Cfunc_readline(0x3ee2010, 0x203e00000002)
    jnk/test/_obj/_cgo_defun.c:42 +0x2f
main.main()
    jnk/test/_obj/test.cgo1.go:10 +0x3a


Here is the backtrace from GDB:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7bc23c5 in ?? () from /lib/libreadline.so.6
(gdb) bt
#0  0x00007ffff7bc23c5 in ?? () from /lib/libreadline.so.6
#1  <signal handler called>
#2  runtime.futex () at /home/knuesel/repos/go/src/pkg/runtime/sys_linux_amd64.s:238
#3  0x000000000040d7e1 in runtime.futexsleep (addr=void, val=void, ns=void) at
/home/knuesel/repos/go/src/pkg/runtime/thread_linux.c:62
#4  0x0000000000403a87 in runtime.notetsleep (n=void, ns=void) at
/home/knuesel/repos/go/src/pkg/runtime/lock_futex.c:146
#5  0x0000000000407f18 in runtime.MHeap_Scavenger () at
/home/knuesel/repos/go/src/pkg/runtime/mheap.c:363
#6  0x00000000004093ea in schedunlock () at
/home/knuesel/repos/go/src/pkg/runtime/proc.c:267
#7  0x0000000000000000 in ?? ()



Which compiler are you using (5g, 6g, 8g, gccgo)?
6g

Which operating system are you using?
Ubuntu lucid

Which version are you using?  (run 'go version')
1.0.3

Please provide any additional information below.
Tested with readline 5 and readline 6
@minux
Copy link
Member

minux commented Oct 8, 2012

Comment 1:

this issue is difficult to fix.
libreadline registered a signal handler of its own.
however, when the signal comes, it runs on Go's segmented stack, and it will surely
crash.
one possible solution is that we export our own sigaction and signal and override libc
version
of these two functions so that we can use cgo bridge to call that signal handler on C
stack.

@minux
Copy link
Member

minux commented Oct 8, 2012

Comment 2:

Labels changed: removed go1.1.

Status changed to Thinking.

@knuesel
Copy link
Author

knuesel commented Oct 8, 2012

Comment 3:

I also noticed that readline in cgo doesn't handle SIGINT as documented (no crash but it
looks like readline's handler is not called). I supposed it is the same issue?

@rsc
Copy link
Contributor

rsc commented Oct 9, 2012

Comment 4:

Can you tell libreadline not to install its own signal handlers?

@knuesel
Copy link
Author

knuesel commented Oct 9, 2012

Comment 5:

Yes I can disable readline's signal handling and do the processing manually. Also,
readline provides e.g. cleanup functions I can call to process SIGINT correctly, in
particular to restore the terminal attributes.
It might take a bit more work to have the readline() call return to the caller in Go
(while in C doing fclose(stdin) is enough).
Also, from the perspective of a readline binding package, it would be nice to emulate
the default readline behavior of catching SIGINT, doing the cleanup and resending the
signal. However this would require support from the os/signal package to temporarily
remove existing SIGINT handlers (with the current API one can only add a handler, which
results in a race condition if another SIGINT handler calls os.Exit() before cleanup is
done).

@rsc
Copy link
Contributor

rsc commented Dec 30, 2012

Comment 6:

Labels changed: added priority-later, removed priority-triage.

@rsc
Copy link
Contributor

rsc commented Jul 25, 2013

Comment 7:

Issue #5287 has been merged into this issue.

@rsc
Copy link
Contributor

rsc commented Jul 30, 2013

Comment 8:

Go's signal handlers must not be overridden. I don't see any way around this.

Status changed to Unfortunate.

@quarnster
Copy link

Comment 9:

> Go's signal handlers must not be overridden. I don't see any way around this.
As this has come up yet again via issue #7227, I have to question this. Why not use
kqueue with signal filters on the BSDs and use signalfd() on Linux? That'd allow Go to
receive the signals no matter what the handler happen to be set to by 3rdparties.

@ianlancetaylor
Copy link
Contributor

Comment 10:

Please don't start discussion on closed issues.  The place for discussion is golang-dev.
 Thanks.

@minux
Copy link
Member

minux commented Feb 1, 2014

Comment 11:

because for some signals, it's not possible to use signalfd/kqueue, our signal handler
needs to modify the thread context.

This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants