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

Segfault after obspy.read #1658

Merged
merged 9 commits into from Mar 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.txt
Expand Up @@ -88,8 +88,13 @@ master: (doi: 10.5281/zenodo.165135)
get_timing_and_data_quality() function obsolete which is thus
deprecated and will be removed with the next release. The get_flags()
function is also much faster. (see #1141)
* Always hook up the libmseed logging to its Python counterpart to avoid
some rare segfaults. (see #1658)
* Update to libmseed v2.19.2 (see #1703).
* Correctly read MiniSEED files with a data offset of 48 bytes (see #1540).
* InternalMSEEDReadingError now called InternalMSEEDError and
InternalMSEEDReadingWarning now called of InternalMSEEDWarning as both
can now also be raised in non-reading contexts (see #1658).
- obspy.io.nlloc:
* Set preferred origin of event (see #1570)
- obspy.io.nordic:
Expand Down
4 changes: 2 additions & 2 deletions obspy/io/mseed/__init__.py
Expand Up @@ -146,11 +146,11 @@
from future.builtins import * # NOQA


class InternalMSEEDReadingError(Exception):
class InternalMSEEDError(Exception):
pass


class InternalMSEEDReadingWarning(UserWarning):
class InternalMSEEDWarning(UserWarning):
pass


Expand Down
58 changes: 22 additions & 36 deletions obspy/io/mseed/core.py
Expand Up @@ -17,7 +17,7 @@

from obspy import Stream, Trace, UTCDateTime
from obspy.core.util import NATIVE_BYTEORDER
from . import util, InternalMSEEDReadingError, InternalMSEEDReadingWarning
from . import util, InternalMSEEDError
from .headers import (DATATYPES, ENCODINGS, HPTERROR, HPTMODULUS, SAMPLETYPE,
SEED_CONTROL_HEADERS, UNSUPPORTED_ENCODINGS,
VALID_CONTROL_HEADERS, VALID_RECORD_LENGTHS, Selections,
Expand Down Expand Up @@ -371,48 +371,34 @@ def allocate_data(samplecount, sampletype):
# it hopefully works on 32 and 64 bit systems.
alloc_data = C.CFUNCTYPE(C.c_longlong, C.c_int, C.c_char)(allocate_data)

# Collect exceptions. They cannot be raised in the callback as they
# could never be caught then. They are collected an raised later on.
_errs_and_warnings = []

def log_error_or_warning(msg):
msg = msg.decode()
if msg.startswith("ERROR: "):
_errs_and_warnings.append(
InternalMSEEDReadingError(msg[7:].strip()))
if msg.startswith("INFO: "):
msg = msg[6:].strip()
try:
verbose = int(verbose)
except Exception:
verbose = 0

clibmseed.verbose = bool(verbose)
try:
lil = clibmseed.readMSEEDBuffer(
bfr_np, buflen, selections, C.c_int8(unpack_data),
reclen, C.c_int8(verbose), C.c_int8(details), header_byteorder,
alloc_data)
except InternalMSEEDError as e:
msg = e.args[0]
if offset and offset in str(e):
# Append the offset of the full SEED header if necessary. That way
# the C code does not have to deal with it.
if offset and "offset" in msg:
msg = ("%s The file contains a %i byte dataless part at the "
msg = ("%s\nThe file contains a %i byte dataless part at the "
"beginning. Make sure to add that to the reported "
"offset to get the actual location in the file." % (
msg, offset))
_errs_and_warnings.append((msg, InternalMSEEDReadingWarning))

diag_print = C.CFUNCTYPE(C.c_void_p, C.c_char_p)(log_error_or_warning)

def log_message(msg):
print(msg[6:].strip())
log_print = C.CFUNCTYPE(C.c_void_p, C.c_char_p)(log_message)

try:
verbose = int(verbose)
except Exception:
verbose = 0

lil = clibmseed.readMSEEDBuffer(
bfr_np, buflen, selections, C.c_int8(unpack_data),
reclen, C.c_int8(verbose), C.c_int8(details), header_byteorder,
alloc_data, diag_print, log_print)

for _i in _errs_and_warnings:
if isinstance(_i, InternalMSEEDReadingError):
raise _i
warnings.warn(*_i)
raise InternalMSEEDError(msg)
else:
raise
finally:
# Make sure to reset the verbosity.
clibmseed.verbose = True

# XXX: Check if the freeing works.
del selections

traces = []
Expand Down