Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
W
wendelin.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Joshua
wendelin.core
Commits
7a837040
Commit
7a837040
authored
Jun 13, 2019
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
X print wcfs.py py-level traceback on SIGBUS (e.g. wcfs.go aborting due to bug/panic)
Needs
https://github.com/cython/cython/pull/2997
parent
d8d42734
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
66 additions
and
3 deletions
+66
-3
wcfs/internal/wcfs_test.pyx
wcfs/internal/wcfs_test.pyx
+59
-0
wcfs/wcfs_test.py
wcfs/wcfs_test.py
+7
-3
No files found.
wcfs/internal/wcfs_test.pyx
View file @
7a837040
...
@@ -21,9 +21,68 @@
...
@@ -21,9 +21,68 @@
"""Module wcfs_test complements wcfs_test.py with things that are impossible to implement in Python"""
"""Module wcfs_test complements wcfs_test.py with things that are impossible to implement in Python"""
from
posix.signal
cimport
sigaction
,
sigaction_t
,
siginfo_t
,
SA_SIGINFO
from
libc.signal
cimport
SIGBUS
from
libc.stdlib
cimport
abort
from
libc.string
cimport
strlen
from
posix.unistd
cimport
write
,
sleep
from
cpython.exc
cimport
PyErr_SetFromErrno
from
cpython.pystate
cimport
PyGILState_Ensure
,
PyGILState_Release
,
PyGILState_STATE
# XXX -> cpython.lifecycle? .run ?
cdef
extern
from
"Python.h"
:
int
PyRun_SimpleString
(
const
char
*
)
# read0_nogil accesses mem[0] with GIL released and returns first byte read from there.
# read0_nogil accesses mem[0] with GIL released and returns first byte read from there.
def
read0_nogil
(
const
unsigned
char
[::
1
]
mem
not
None
)
->
int
:
def
read0_nogil
(
const
unsigned
char
[::
1
]
mem
not
None
)
->
int
:
cdef
unsigned
char
b
cdef
unsigned
char
b
with
nogil
:
with
nogil
:
b
=
mem
[
0
]
b
=
mem
[
0
]
return
b
return
b
# ---- signal handling ----
# XXX -> golang.signal ?
# install_sigbus_trap installs SIGBUS handler that prints python-level
# traceback before aborting.
#
# Such handler is useful, because when wcfs.go bugs/panics while handling file
# access from wcfs.py, wcfs.py receives SIGBUS signal and by default aborts.
def
install_sigbus_trap
():
cdef
sigaction_t
act
act
.
sa_sigaction
=
on_sigbus
act
.
sa_flags
=
SA_SIGINFO
cdef
int
err
=
sigaction
(
SIGBUS
,
&
act
,
NULL
)
if
err
:
PyErr_SetFromErrno
(
OSError
)
cdef
void
on_sigbus
(
int
sig
,
siginfo_t
*
si
,
void
*
_uc
):
# - wait a bit to give time for other threads to complete their exception dumps
# (e.g. getting "Transport endpoint is not connected" after wcfs.go dying)
# - dump py-level traceback and abort.
# TODO turn SIGBUS into python-level exception? (see sigpanic in Go how to do).
writeerr
(
"
\
n
C: SIGBUS received; giving time to other threads"
+
"to dump their exceptions (if any) ...
\
n
"
)
cdef
PyGILState_STATE
gstate
=
PyGILState_Ensure
()
PyGILState_Release
(
gstate
)
sleep
(
1
)
writeerr
(
"
\
n
C: SIGBUS thread traceback:
\
n
"
)
PyGILState_Ensure
()
PyRun_SimpleString
(
"import traceback; traceback.print_stack()"
)
writeerr
(
"-> SIGBUS
\
n
"
);
abort
()
# writeerr writes msg to stderr without depending on stdio buffering and locking.
cdef
void
writeerr
(
const
char
*
msg
):
cdef
ssize_t
n
,
left
=
strlen
(
msg
)
while
left
>
0
:
n
=
write
(
2
,
msg
,
left
)
if
n
==
-
1
:
return
# nothing we can do under crash?
left
-=
n
msg
+=
n
wcfs/wcfs_test.py
View file @
7a837040
...
@@ -42,7 +42,7 @@ from zodbtools.util import ashex as h, fromhex
...
@@ -42,7 +42,7 @@ from zodbtools.util import ashex as h, fromhex
from
pytest
import
raises
from
pytest
import
raises
from
six
import
reraise
from
six
import
reraise
from
.internal
import
mm
from
.internal
import
mm
from
.internal.wcfs_test
import
read0_nogil
from
.internal.wcfs_test
import
read0_nogil
,
install_sigbus_trap
# setup:
# setup:
# - create test database, compute zurl and mountpoint for wcfs
# - create test database, compute zurl and mountpoint for wcfs
...
@@ -52,6 +52,10 @@ testdb = None
...
@@ -52,6 +52,10 @@ testdb = None
testzurl
=
None
# URL of testdb
testzurl
=
None
# URL of testdb
testmntpt
=
None
# wcfs is mounted here
testmntpt
=
None
# wcfs is mounted here
def
setup_module
():
def
setup_module
():
# if wcfs.py receives SIGBUS because wcfs.go panics, we want to see
# python-level traceback instead of being killed.
install_sigbus_trap
()
global
testdb
,
testzurl
,
testmntpt
global
testdb
,
testzurl
,
testmntpt
testdb
=
getTestDB
()
testdb
=
getTestDB
()
testdb
.
setup
()
testdb
.
setup
()
...
@@ -1172,7 +1176,7 @@ def test_wcfs():
...
@@ -1172,7 +1176,7 @@ def test_wcfs():
# >>> XXX commit data to not yet accessed f part - nothing happens
# >>> XXX commit data to not yet accessed f part - nothing happens
"""
#
"""
# >>> invalidation protocol
# >>> invalidation protocol
print
(
'
\
n
\
n
inv. protocol
\
n
\
n
'
)
print
(
'
\
n
\
n
inv. protocol
\
n
\
n
'
)
...
@@ -1238,7 +1242,7 @@ def test_wcfs():
...
@@ -1238,7 +1242,7 @@ def test_wcfs():
for
at
in
revv
[
1
:]:
for
at
in
revv
[
1
:]:
wl
.
watch
(
zf
,
at
)
wl
.
watch
(
zf
,
at
)
wl
.
close
()
wl
.
close
()
"""
#
"""
# XXX move before setup watch?
# XXX move before setup watch?
print
(
'
\
n
\
n
\
n
\
n
WATCH+COMMIT
\
n
\
n
'
)
print
(
'
\
n
\
n
\
n
\
n
WATCH+COMMIT
\
n
\
n
'
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment