Numpy: Crash dans `np.vdot` pour un objet de type tableau

Créé le 10 août 2019  ·  6Commentaires  ·  Source: numpy/numpy

numpy.vdot peut segfault s'il est passé un objet qui implémente __array__ d'une manière non standard.

Le segfault se produit dans cette ligne de code:
https://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/multiarraymodule.c#L2245
puisque type peut être NULL si PyArray_DescrFromType échoue.

Exemple de code de reproduction:

import numpy as np

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

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

Message d'erreur:

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

Informations sur la version Numpy / Python:

J'ai reproduit ceci à la fois sur Mac OS X avec:

1.17.0 3.7.2 (default, Jan 16 2019, 11:36:28)
[Clang 10.0.0 (clang-1000.11.45.2)]

et sur une version Linux interne.

Ce problème a été signalé à l'origine sous la forme https://github.com/google/jax/issues/1162

00 - Bug

Tous les 6 commentaires

Hmm, vdot vérifie ce que le dtype de sortie sera à l'avance (ce qui, je suppose, est très bien). Cependant, cette fonction peut échouer et renvoyer NPY_NOTYPE , elle devrait donc renvoyer une erreur lorsque NPY_NOTYPE est renvoyé. C'est dans https://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/multiarraymodule.c#L2241 (et la ligne suivante), l'erreur que vous voyez est un retour d'erreur plus tard, mais je pense que cette fonction ne devrait vraiment pas renvoyer d'erreur (même si ce serait bien d'ajouter une vérification d'erreur là aussi).

Voulez-vous faire un PR?

(Cela pourrait être bien de vérifier s'il existe d'autres utilisations similaires où la vérification des erreurs est manquante.)

Salut,
Je suis un nouveau venu et j'aimerais travailler sur cette question. Des pistes sur par où commencer?
Merci d'avance.

Découvrez notre workflow de développement . Ensuite, vous devriez arriver à un point où vous pouvez exécuter python runtests.py sur la branche master ( git checkout master; git clean -xfd; python runtests.py ).

Lorsque vous êtes configuré, vous pouvez commencer à pirater: créez une branche, ajoutez un test qui échoue ( numpy/core/tests/teste_multiarray.py dans TestVDot serait un bon endroit), essayez de corriger le code C à partir de l'indice ci-dessus . Si vous êtes bloqué, n'hésitez pas à demander de l'aide, plus vous pourrez montrer que vous avez fait un véritable effort pour suivre la documentation et les conseils, mieux ce sera.

Bienvenue @ Soniyanayak51!

Pour ajouter à ce que @mattip a dit: une petite information qui manque dans nos documents (je pense) est la façon dont nous travaillons sur les problèmes. Nous n'utilisons pas la fonctionnalité "assignés" de GitHub, donc à moins qu'il ne soit clair d'après les récents commentaires / relations publiques que quelqu'un travaille activement sur un problème, vous pouvez simplement vous y plonger.

@rgommers @mattip J'ai ajouté des vérifications pour les types obtenus à partir de PyArray_DescrFromType (). Je ne suis pas sûr de devoir les ajouter également pour PyArray_DESCR ().
De plus, à propos de l'ajout de tests dans test_multiarray.py, dois-je ajouter un test_PyArrayType et ajouter des tests où le type est NULL? Je ne sais pas comment aller de l'avant avec l'ajout de tests.

@rgommers @mattip J'ai ajouté des vérifications pour les types obtenus à partir de PyArray_DescrFromType (). Je ne suis pas sûr de devoir les ajouter également pour PyArray_DESCR ().
De plus, à propos de l'ajout de tests dans test_multiarray.py, dois-je ajouter un test_PyArrayType et ajouter des tests où le type est NULL? Je ne sais pas comment aller de l'avant avec l'ajout de tests.

On dirait que @mattip a répondu à cela en partie sur le PR (je pense). Il vaut probablement mieux garder la conversation là-bas.

dois-je ajouter un test_PyArrayType et ajouter des tests où le type est NULL?

Pour ajouter un peu: le principe pour ajouter des tests est normalement de ne tester que l'API publique. Alors tu prendrais

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

à partir de la description du problème ci-dessus, et ajoutez-le comme test. Il ne semble pas nécessaire de tester l'API C séparément.

Cette page vous a été utile?
0 / 5 - 0 notes