Skip to content

Commit c0f9e3d

Browse files
chressiestapelberg
authored andcommitted
glog: don't use SIGABRT on platforms that don't support signals
cl/517387773 (google-internal)
1 parent 9c9801e commit c0f9e3d

File tree

4 files changed

+122
-29
lines changed

4 files changed

+122
-29
lines changed

glog.go

-29
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ import (
9292
"strconv"
9393
"sync"
9494
"sync/atomic"
95-
"syscall"
9695
"time"
9796

9897
"github.com/golang/glog/internal/logsink"
@@ -524,34 +523,6 @@ func fatalf(depth int, format string, args ...any) {
524523
os.Exit(2) // Exit with the same code as the default SIGABRT handler.
525524
}
526525

527-
// abortProcess attempts to kill the current process in a way that will dump the
528-
// currently-running goroutines someplace useful (Coroner or stderr).
529-
//
530-
// It does this by sending SIGABRT to the current process. Unfortunately, the
531-
// signal may or may not be delivered to the current thread; in order to do that
532-
// portably, we would need to add a cgo dependency and call pthread_kill.
533-
//
534-
// If successful, abortProcess does not return.
535-
func abortProcess() error {
536-
p, err := os.FindProcess(os.Getpid())
537-
if err != nil {
538-
return err
539-
}
540-
if err := p.Signal(syscall.SIGABRT); err != nil {
541-
return err
542-
}
543-
544-
// Sent the signal. Now we wait for it to arrive and any SIGABRT handlers to
545-
// run (and eventually terminate the process themselves).
546-
//
547-
// We could just "select{}" here, but there's an outside chance that would
548-
// trigger the runtime's deadlock detector if there happen not to be any
549-
// background goroutines running. So we'll sleep a while first to give
550-
// the signal some time.
551-
time.Sleep(10 * time.Second)
552-
select {}
553-
}
554-
555526
// Fatal logs to the FATAL, ERROR, WARNING, and INFO logs,
556527
// including a stack trace of all running goroutines, then calls os.Exit(2).
557528
// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.

glog_file_linux.go

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Go support for leveled logs, analogous to https://github.com/google/glog.
2+
//
3+
// Copyright 2023 Google Inc. All Rights Reserved.
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
//go:build linux
18+
19+
package glog
20+
21+
import (
22+
"errors"
23+
"runtime"
24+
"syscall"
25+
)
26+
27+
// abortProcess attempts to kill the current process in a way that will dump the
28+
// currently-running goroutines someplace useful (like stderr).
29+
//
30+
// It does this by sending SIGABRT to the current thread.
31+
//
32+
// If successful, abortProcess does not return.
33+
func abortProcess() error {
34+
runtime.LockOSThread()
35+
if err := syscall.Tgkill(syscall.Getpid(), syscall.Gettid(), syscall.SIGABRT); err != nil {
36+
return err
37+
}
38+
return errors.New("log: killed current thread with SIGABRT, but still running")
39+
}

glog_file_other.go

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Go support for leveled logs, analogous to https://github.com/google/glog.
2+
//
3+
// Copyright 2023 Google Inc. All Rights Reserved.
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
//go:build !(unix || windows)
18+
19+
package glog
20+
21+
import (
22+
"fmt"
23+
"runtime"
24+
)
25+
26+
// abortProcess returns an error on platforms that presumably don't support signals.
27+
func abortProcess() error {
28+
return fmt.Errorf("not sending SIGABRT (%s/%s does not support signals), falling back", runtime.GOOS, runtime.GOARCH)
29+
30+
}

glog_file_posix.go

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Go support for leveled logs, analogous to https://github.com/google/glog.
2+
//
3+
// Copyright 2023 Google Inc. All Rights Reserved.
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
//go:build (unix || windows) && !linux
18+
19+
package glog
20+
21+
import (
22+
"os"
23+
"syscall"
24+
"time"
25+
)
26+
27+
// abortProcess attempts to kill the current process in a way that will dump the
28+
// currently-running goroutines someplace useful (like stderr).
29+
//
30+
// It does this by sending SIGABRT to the current process. Unfortunately, the
31+
// signal may or may not be delivered to the current thread; in order to do that
32+
// portably, we would need to add a cgo dependency and call pthread_kill.
33+
//
34+
// If successful, abortProcess does not return.
35+
func abortProcess() error {
36+
p, err := os.FindProcess(os.Getpid())
37+
if err != nil {
38+
return err
39+
}
40+
if err := p.Signal(syscall.SIGABRT); err != nil {
41+
return err
42+
}
43+
44+
// Sent the signal. Now we wait for it to arrive and any SIGABRT handlers to
45+
// run (and eventually terminate the process themselves).
46+
//
47+
// We could just "select{}" here, but there's an outside chance that would
48+
// trigger the runtime's deadlock detector if there happen not to be any
49+
// background goroutines running. So we'll sleep a while first to give
50+
// the signal some time.
51+
time.Sleep(10 * time.Second)
52+
select {}
53+
}

0 commit comments

Comments
 (0)