Numpy: Falha em `np.vdot` para objeto tipo array

Criado em 10 ago. 2019  ·  6Comentários  ·  Fonte: numpy/numpy

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.

Reproduzindo exemplo de código:

import numpy as np

class Foo(object):
     def __array__(self, a):
         return self

np.vdot(Foo(), Foo())

Mensagem de erro:

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

Informações sobre a versão Numpy / Python:

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

00 - Bug

Todos 6 comentários

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.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

ghost picture ghost  ·  4Comentários

keithbriggs picture keithbriggs  ·  3Comentários

navytux picture navytux  ·  4Comentários

dmvianna picture dmvianna  ·  4Comentários

marcocaccin picture marcocaccin  ·  4Comentários