Issue 1:
Using numpy version 1.10.4. (Python 2.7)

If I do the following I get a segmentation fault:

import numpy as np
x = [np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17,
18, 19]), np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17,
18, 19]), np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 17, 18,
19]), np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17,
19]), np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17,
18, 19]), np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 17, 19]), np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17,
18, 19]), np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 17, 18,
19]), np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17,
18, 19]), np.array([ 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 19]), np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17,
18, 19]), np.array([ 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 17, 18, 19]), np.array([ 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 17, 18, 19]), np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 17, 18,
19]), np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17,
18, 19]), np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17,
18, 19]), np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17,
19]), np.array([ 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 17, 19]), np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17,
18, 19]), np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 17, 18,
19])]

np.unique(x)

Running it through gdb I get the following backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000478528 in ?? ()
(gdb) backtrace
#0 0x0000000000478528 in ?? ()
#1 0x0000000000418dc7 in PyObject_Compare ()
#2 0x00007ffff6868c16 in npy_quicksort (start=start@entry=0x1af8d30, num=num@entry=20, varr=varr@entry=0x7fffec878300) at numpy/core/src/npysort/quicksort.c.src:401
#3 0x00007ffff67ebe35 in _new_sortlike (op=op@entry=0x7fffec878300, axis=0, sort=0x7ffff6868970 <npy_quicksort>, part=part@entry=0x0, kth=kth@entry=0x0, nkth=nkth@entry=0)
at numpy/core/src/multinp.array/item_selection.c:871
#4 0x00007ffff67ee6f2 in Pynp.Array_Sort (op=op@entry=0x7fffec878300, axis=<optimized out>, which=<optimized out>) at numpy/core/src/multinp.array/item_selection.c:1146
#5 0x00007ffff682eab1 in np.array_sort (self=0x7fffec878300, args=<optimized out>, kwds=<optimized out>) at numpy/core/src/multinp.array/methods.c:1159
#6 0x000000000049968d in PyEval_EvalFrameEx ()
#7 0x00000000004a090c in PyEval_EvalCodeEx ()
#8 0x0000000000499a52 in PyEval_EvalFrameEx ()
#9 0x0000000000499ef2 in PyEval_EvalFrameEx ()
#10 0x0000000000499ef2 in PyEval_EvalFrameEx ()
#11 0x0000000000499ef2 in PyEval_EvalFrameEx ()
#12 0x00000000004a090c in PyEval_EvalCodeEx ()
#13 0x0000000000499a52 in PyEval_EvalFrameEx ()
#14 0x00000000004a090c in PyEval_EvalCodeEx ()
#15 0x0000000000499a52 in PyEval_EvalFrameEx ()
#16 0x00000000004a090c in PyEval_EvalCodeEx ()
#17 0x0000000000499a52 in PyEval_EvalFrameEx ()
#18 0x0000000000499ef2 in PyEval_EvalFrameEx ()
#19 0x00000000004a1634 in ?? ()
#20 0x000000000044e4a5 in PyRun_FileExFlags ()
#21 0x000000000044ec9f in PyRun_SimpleFileExFlags ()
#22 0x000000000044f904 in Py_Main ()
#23 0x00007ffff7818ec5 in __libc_start_main (main=0x44f9c2 <main>, argc=2, argv=0x7fffffffdfb8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>,
stack_end=0x7fffffffdfa8) at libc-start.c:287
#24 0x0000000000578c4e in _start ()

I know I shouldn't be passing in a list of unequal sized arrays into this function (forgot to concatenate them first) but would be useful to have a more useful exception if I try doing this to help me find my bug more quickly.

Note on further investigation I find that this sometimes happens:

In [7]: z = [np.array([1,3,4]), np.array([1,2]), np.array([1,4])]

In [8]: np.unique(z)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-8-d290d6500455> in <module>()
----> 1 np.unique(z)

/usr/local/lib/python2.7/site-packages/numpy/lib/arraysetops.pyc in unique(ar, return_index, return_inverse, return_counts)
198 ar.sort()
199 aux = ar
--> 200 flag = np.concatenate(([True], aux[1:] != aux[:-1]))
201
202 if not optional_returns:

ValueError: all the input arrays must have same number of dimensions

Whereas sometimes it does not seem to try to concatenate the arrays and does the operation without a seg fault or exception:

In [9]: w = [np.array([1,3,4]), np.array([1,2])]

In [10]: np.unique(w)
Out[10]: array([array([1, 2]), array([1, 3, 4])], dtype=object)

Thanks.

Issue 2:
Running the example from #3879 with current master segfaults:

>>> import numpy as np
>>> class Raiser(object):
... def raises_anything(*args, **kwargs):
... raise TypeError("SOMETHING ERRORED")
... __eq__ = __ne__ = __lt__ = __gt__ = __ge__ = __le__ = raises_anything
...
>>> arr = np.array([Raiser() for n in range(10)] + list(range(10)))
>>> arr.sort()
/Users/jaimefrio/miniconda/envs/numpydev/bin/python.app: line 3: 41998 Segmentation fault: 11 /Users/jaimefrio/miniconda/envs/numpydev/python.app/Contents/MacOS/python "$@"

This happens because of the changes introduced in #5670. We now use the same quicksort algorithm for objects as for other numeric types, instead of the stdlib's qsort. Our algorithm sorts the first, last and middle items of the array, both to choose the middle one as the pivot, and to have the first and last items as guards against run away pointers, which lets us avoid extra checks in the innermost loop.

Because on failure PyObject_Compare returns -1, and we do no checking if an error was raised in OBJECT_compare, these end guards do not serve their purpose anymore, hence the runaway pointer and the segfault.

I see two potential solutions:

Modify npy_quicksort's inner loop to do explicit inbounds checks before dereferencing a pointer.

Modify OBJECT_compare to check if PyErr_Occurred, and return 0 rather than -1. This would unify the behavior with Python 3, where PyObject_RichCompareBool is called with Py_LT, then with Py_GT, and if none succeeds it returns 0 without explicitly checking with Py_EQ.

I prefer option 2.