| File: | build/../torch/csrc/autograd/python_anomaly_mode.cpp |
| Warning: | line 48, column 36 PyObject ownership leak with reference count of 1 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | #include <torch/csrc/autograd/python_anomaly_mode.h> | |||
| 2 | #include <c10/util/Exception.h> | |||
| 3 | #include <pybind11/pybind11.h> | |||
| 4 | #include <torch/csrc/Exceptions.h> | |||
| 5 | #include <torch/csrc/autograd/python_cpp_function.h> | |||
| 6 | #include <torch/csrc/python_headers.h> | |||
| 7 | #include <torch/csrc/utils/auto_gil.h> | |||
| 8 | #include <torch/csrc/utils/object_ptr.h> | |||
| 9 | #include <torch/csrc/utils/python_strings.h> | |||
| 10 | ||||
| 11 | #include <iostream> | |||
| 12 | ||||
| 13 | namespace torch { namespace autograd { | |||
| 14 | ||||
| 15 | void PyAnomalyMetadata::store_stack() { | |||
| 16 | pybind11::gil_scoped_acquire gil; | |||
| 17 | THPObjectPtr mod(PyImport_ImportModule("traceback")); | |||
| 18 | if (!mod) { | |||
| 19 | throw python_error(); | |||
| 20 | } | |||
| 21 | ||||
| 22 | THPObjectPtr list(PyObject_CallMethod(mod.get(), "format_stack", "")); | |||
| 23 | if (!list) { | |||
| 24 | throw python_error(); | |||
| 25 | } | |||
| 26 | ||||
| 27 | if (PyDict_SetItemString(dict(), ANOMALY_TRACE_KEY, list.get())) { | |||
| 28 | throw python_error(); | |||
| 29 | } | |||
| 30 | } | |||
| 31 | ||||
| 32 | void PyAnomalyMetadata::print_stack(const std::string& current_node_name) { | |||
| 33 | pybind11::gil_scoped_acquire gil; | |||
| 34 | if (!PyDict_Check(dict())((((((PyObject*)(dict()))->ob_type))->tp_flags & (( 1UL << 29))) != 0)) { | |||
| ||||
| 35 | throw std::runtime_error("Anomaly metadata is not a python dictionary."); | |||
| 36 | } | |||
| 37 | PyObject* trace_stack = PyDict_GetItemString(dict(), ANOMALY_TRACE_KEY); | |||
| 38 | _print_stack(trace_stack, current_node_name, false); | |||
| 39 | PyObject* pyparent(PyDict_GetItemString(dict(), ANOMALY_PARENT_KEY)); | |||
| 40 | ||||
| 41 | // if there is no "parent_" in metadata, then it means this metadata's node | |||
| 42 | // is the root and stop printing the traceback | |||
| 43 | while (pyparent) { | |||
| 44 | THPObjectPtr parent_metadata(PyObject_GetAttrString(pyparent, "metadata")); | |||
| 45 | if (!parent_metadata) { | |||
| 46 | throw python_error(); | |||
| 47 | } | |||
| 48 | THPObjectPtr parent_name_pyobj(PyObject_CallMethod(pyparent, "name", "")); | |||
| ||||
| 49 | if (!parent_name_pyobj) { | |||
| 50 | throw python_error(); | |||
| 51 | } | |||
| 52 | const char* parent_name_char = PyUnicode_AsUTF8(parent_name_pyobj.get()); | |||
| 53 | if (!parent_name_char) { | |||
| 54 | throw python_error(); | |||
| 55 | } | |||
| 56 | const std::string parent_name(parent_name_char); | |||
| 57 | PyObject* parent_stack = PyDict_GetItemString(parent_metadata.get(), ANOMALY_TRACE_KEY); | |||
| 58 | _print_stack(parent_stack, parent_name, true); | |||
| 59 | // get the parent of this node, if this node is a root, pyparent is simply null | |||
| 60 | pyparent = PyDict_GetItemString(parent_metadata.get(), ANOMALY_PARENT_KEY); | |||
| 61 | } | |||
| 62 | } | |||
| 63 | ||||
| 64 | void PyAnomalyMetadata::assign_parent(const std::shared_ptr<Node>& parent_node) { | |||
| 65 | // assign the python object of parent_node in metadata["parent_"] | |||
| 66 | // if parent_node is nullptr, then do nothing (it can mean that "parent_" key | |||
| 67 | // is not in metadata) | |||
| 68 | ||||
| 69 | pybind11::gil_scoped_acquire gil; | |||
| 70 | if (!parent_node) return; | |||
| 71 | ||||
| 72 | THPObjectPtr parent_node_(functionToPyObject(parent_node)); | |||
| 73 | if (!parent_node_) { | |||
| 74 | throw python_error(); | |||
| 75 | } | |||
| 76 | if (PyDict_SetItemString(dict(), ANOMALY_PARENT_KEY, parent_node_.get())) { | |||
| 77 | throw python_error(); | |||
| 78 | } | |||
| 79 | } | |||
| 80 | ||||
| 81 | void _print_stack(PyObject* stack, const std::string& current_node_name, bool is_parent) { | |||
| 82 | if (!stack) { | |||
| 83 | TORCH_WARN("Error detected in ", current_node_name, ". ",::c10::Warning::warn( {__func__, "../torch/csrc/autograd/python_anomaly_mode.cpp" , static_cast<uint32_t>(85)}, ::c10::str("Error detected in " , current_node_name, ". ", "No forward pass information available. Enable detect anomaly " "during forward pass for more information."), false) | |||
| 84 | "No forward pass information available. Enable detect anomaly "::c10::Warning::warn( {__func__, "../torch/csrc/autograd/python_anomaly_mode.cpp" , static_cast<uint32_t>(85)}, ::c10::str("Error detected in " , current_node_name, ". ", "No forward pass information available. Enable detect anomaly " "during forward pass for more information."), false) | |||
| 85 | "during forward pass for more information.")::c10::Warning::warn( {__func__, "../torch/csrc/autograd/python_anomaly_mode.cpp" , static_cast<uint32_t>(85)}, ::c10::str("Error detected in " , current_node_name, ". ", "No forward pass information available. Enable detect anomaly " "during forward pass for more information."), false); | |||
| 86 | return; | |||
| 87 | } | |||
| 88 | ||||
| 89 | THPObjectPtr empty_string(PyUnicode_FromString("")); | |||
| 90 | if (!empty_string) { | |||
| 91 | throw python_error(); | |||
| 92 | } | |||
| 93 | ||||
| 94 | // stack is a list of Python strings ending with newlines. Use join to convert | |||
| 95 | // to a single string. | |||
| 96 | THPObjectPtr msg(PyUnicode_Join(empty_string, stack)); | |||
| 97 | if (!msg) { | |||
| 98 | throw python_error(); | |||
| 99 | } | |||
| 100 | ||||
| 101 | if (!is_parent) { | |||
| 102 | TORCH_WARN("Error detected in ", current_node_name, ". ",::c10::Warning::warn( {__func__, "../torch/csrc/autograd/python_anomaly_mode.cpp" , static_cast<uint32_t>(104)}, ::c10::str("Error detected in " , current_node_name, ". ", "Traceback of forward call that caused the error:\n" , THPUtils_unpackString(msg.get())), false) | |||
| 103 | "Traceback of forward call that caused the error:\n",::c10::Warning::warn( {__func__, "../torch/csrc/autograd/python_anomaly_mode.cpp" , static_cast<uint32_t>(104)}, ::c10::str("Error detected in " , current_node_name, ". ", "Traceback of forward call that caused the error:\n" , THPUtils_unpackString(msg.get())), false) | |||
| 104 | THPUtils_unpackString(msg.get()))::c10::Warning::warn( {__func__, "../torch/csrc/autograd/python_anomaly_mode.cpp" , static_cast<uint32_t>(104)}, ::c10::str("Error detected in " , current_node_name, ". ", "Traceback of forward call that caused the error:\n" , THPUtils_unpackString(msg.get())), false); | |||
| 105 | } else { | |||
| 106 | TORCH_WARN("\n\n",::c10::Warning::warn( {__func__, "../torch/csrc/autograd/python_anomaly_mode.cpp" , static_cast<uint32_t>(109)}, ::c10::str("\n\n", "Previous calculation was induced by " , current_node_name, ". " "Traceback of forward call that induced the previous calculation:\n" , THPUtils_unpackString(msg.get())), false) | |||
| 107 | "Previous calculation was induced by ", current_node_name, ". "::c10::Warning::warn( {__func__, "../torch/csrc/autograd/python_anomaly_mode.cpp" , static_cast<uint32_t>(109)}, ::c10::str("\n\n", "Previous calculation was induced by " , current_node_name, ". " "Traceback of forward call that induced the previous calculation:\n" , THPUtils_unpackString(msg.get())), false) | |||
| 108 | "Traceback of forward call that induced the previous calculation:\n",::c10::Warning::warn( {__func__, "../torch/csrc/autograd/python_anomaly_mode.cpp" , static_cast<uint32_t>(109)}, ::c10::str("\n\n", "Previous calculation was induced by " , current_node_name, ". " "Traceback of forward call that induced the previous calculation:\n" , THPUtils_unpackString(msg.get())), false) | |||
| 109 | THPUtils_unpackString(msg.get()))::c10::Warning::warn( {__func__, "../torch/csrc/autograd/python_anomaly_mode.cpp" , static_cast<uint32_t>(109)}, ::c10::str("\n\n", "Previous calculation was induced by " , current_node_name, ". " "Traceback of forward call that induced the previous calculation:\n" , THPUtils_unpackString(msg.get())), false); | |||
| 110 | } | |||
| 111 | } | |||
| 112 | ||||
| 113 | }} |
| 1 | #ifndef PyObject_CallMethod |
| 2 | struct _object; |
| 3 | typedef struct _object PyObject; |
| 4 | PyObject* clang_analyzer_PyObject_New_Reference(); |
| 5 | PyObject* PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...) { |
| 6 | return clang_analyzer_PyObject_New_Reference(); |
| 7 | } |
| 8 | #else |
| 9 | #warning "API PyObject_CallMethod is defined as a macro." |
| 10 | #endif |