numpy.vdot
pode falhar em segfault se passado um objeto que implementa __array__
de uma forma não padrão.
O segfault acontece nesta linha de código:
https://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/multiarraymodule.c#L2245
já que type
pode ser NULL
se PyArray_DescrFromType
falhar.
import numpy as np
class Foo(object):
def __array__(self, a):
return self
np.vdot(Foo(), Foo())
Backtrace:
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
* frame #0: 0x0000000100cef88e _multiarray_umath.cpython-37m-darwin.so`array_vdot + 126
frame #1: 0x00000001005e0994 python`PyCFunction_Call + 148
frame #2: 0x0000000100c48dc1 _multiarray_umath.cpython-37m-darwin.so`array_implement_array_function + 305
frame #3: 0x00000001005e11b3 python`_PyMethodDef_RawFastCallKeywords + 227
frame #4: 0x00000001005e071c python`_PyCFunction_FastCallKeywords + 44
frame #5: 0x00000001006b6048 python`call_function + 664
frame #6: 0x00000001006b2a18 python`_PyEval_EvalFrameDefault + 27080
frame #7: 0x00000001006b6e45 python`_PyEval_EvalCodeWithName + 2997
frame #8: 0x00000001005e06d6 python`_PyFunction_FastCallKeywords + 230
frame #9: 0x00000001006b60d9 python`call_function + 809
frame #10: 0x00000001006b2987 python`_PyEval_EvalFrameDefault + 26935
frame #11: 0x00000001006b6e45 python`_PyEval_EvalCodeWithName + 2997
frame #12: 0x00000001006abfb0 python`PyEval_EvalCode + 48
frame #13: 0x00000001006ee677 python`PyRun_InteractiveOneObjectEx + 615
frame #14: 0x00000001006ede4e python`PyRun_InteractiveLoopFlags + 190
frame #15: 0x00000001006edd5c python`PyRun_AnyFileExFlags + 60
frame #16: 0x0000000100710c51 python`pymain_main + 7873
frame #17: 0x000000010071127f python`_Py_UnixMain + 111
frame #18: 0x00007fff5f6e63d5 libdyld.dylib`start + 1
Eu reproduzi isso no Mac OS X com:
1.17.0 3.7.2 (default, Jan 16 2019, 11:36:28)
[Clang 10.0.0 (clang-1000.11.45.2)]
e em uma construção Linux interna.
Esse problema foi relatado originalmente como https://github.com/google/jax/issues/1162
Hmm, vdot
verifica qual será o dtype de saída com antecedência (o que eu suponho que esteja bom). No entanto, essa função pode falhar e retornar NPY_NOTYPE
, portanto, deve retornar um erro quando NPY_NOTYPE
for retornado. Isso está em https://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/multiarraymodule.c#L2241 (e na linha seguinte), o erro que você vê é um erro que retorna mais tarde, mas eu acho que essa função realmente não deve retornar um erro (embora fosse bom adicionar uma verificação de erro lá também).
Você quer fazer um PR?
(Pode ser bom verificar se há usos mais semelhantes em que a verificação de erro está faltando.)
Oi,
Sou um novato e gostaria de trabalhar nessa questão. Alguma pista sobre por onde começar?
Desde já, obrigado.
Leia sobre nosso fluxo de trabalho de desenvolvimento . Então você deve chegar a um ponto em que pode executar python runtests.py
do branch master
( git checkout master; git clean -xfd; python runtests.py
).
Quando estiver configurado, você pode começar a hackear: crie um branch, adicione um teste de falha ( numpy/core/tests/teste_multiarray.py
em TestVDot
seria um bom lugar), tente corrigir o código C da dica acima . Se você tiver dúvidas, fique à vontade para pedir ajuda, quanto mais você puder mostrar que fez um verdadeiro esforço para seguir a documentação e as dicas, melhor.
Bem-vindo @ Soniyanayak51!
Para adicionar ao que @mattip disse: um pouco de informação que está faltando em nossos documentos (eu acho) é como trabalhamos nas questões. Não usamos o recurso de "designados" do GitHub, portanto, a menos que fique claro pelos comentários / relações públicas recentes que alguém está trabalhando ativamente em um problema, você pode mergulhar.
@rgommers @mattip Eu adicionei verificações para tipos obtidos em PyArray_DescrFromType (). Não tenho certeza se devo adicioná-los para PyArray_DESCR () também.
Além disso, sobre como adicionar testes em test_multiarray.py, devo adicionar um test_PyArrayType e adicionar testes em que o tipo é NULL? Não tenho certeza de como avançar com a adição de testes.
@rgommers @mattip Eu adicionei verificações para tipos obtidos em PyArray_DescrFromType (). Não tenho certeza se devo adicioná-los para PyArray_DESCR () também.
Além disso, sobre como adicionar testes em test_multiarray.py, devo adicionar um test_PyArrayType e adicionar testes em que o tipo é NULL? Não tenho certeza de como avançar com a adição de testes.
Parece que @mattip respondeu parcialmente no PR (eu acho). Provavelmente melhor manter a conversa lá.
devo adicionar um test_PyArrayType e adicionar testes onde o tipo é NULL?
Para adicionar um pouco: o princípio para adicionar testes normalmente é testar apenas a API pública. Então você pegaria
...
np.vdot(Foo(), Foo())
da descrição do problema acima e adicione-a como um teste. Não parece necessário testar a API C separadamente.