CiscoDevNet / ydk-gen

Generate model-driven APIs from YANG models
http://ciscodevnet.github.io/ydk-gen/
Apache License 2.0
135 stars 74 forks source link

Python crushes while traversing entities to the top level #1031

Closed ygorelik closed 1 year ago

ygorelik commented 3 years ago

Current Behavior

Getting python crush (segmentation fault) while traversing entities to the top level entity.

Steps to Reproduce

Execute the following script:

#!/usr/bin/env python
#
from ydk.services import CRUDService
from ydk.providers import NetconfServiceProvider
from ydk.models.cisco_ios_xr import Cisco_IOS_XR_ipv4_bgp_oper as xr_ipv4_bgp_oper

import logging

def enable_logging(level):
    log = logging.getLogger('ydk')
    log.setLevel(level)
    handler = logging.StreamHandler()
    formatter = logging.Formatter(
            "%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    handler.setFormatter(formatter)
    log.addHandler(handler)

def build_bgp_instance_obj():
    bgp_oper_obj = xr_ipv4_bgp_oper.Bgp()

    bgp_oper_instance_list_obj = xr_ipv4_bgp_oper.Bgp.Instances.Instance()
    bgp_oper_instance_list_obj.instance_name = 'default'
    bgp_oper_obj.instances.instance.append(bgp_oper_instance_list_obj)
    return bgp_oper_instance_list_obj

if __name__ == '__main__':

    enable_logging(logging.INFO)

    provider = NetconfServiceProvider(
        address='sbx-iosxr-mgmt.cisco.com',
        port=10000,
        username='admin',
        password='C1sco12345')

    crud = CRUDService()

    bgp_instance_obj = build_bgp_instance_obj()

    bgp_oper = crud.read(provider, bgp_instance_obj)

Getting the following output:

/Users/ygorelik/venv/bin/python /Users/ygorelik/ydk-gen/scripts/community/xr_bgp_oper.py
2020-11-03 10:02:39,216 - ydk - INFO - Path where models are to be downloaded: /Users/ygorelik/.ydk/sbx-iosxr-mgmt.cisco.com
2020-11-03 10:02:39,250 - ydk - INFO - Connected to sbx-iosxr-mgmt.cisco.com on port 10000 using ssh with timeout of -1

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

Script debugging showed that Python crushes in function ydk.entity_utils._traverse_to_top_entity:

def _traverse_to_top_entity(entity):
    while entity.parent is not None:
        entity = entity.parent    # crushes on execution of this line
    return entity

Note. No issues observed when crud.read called on top level object _bgp_operobj .

System Information

YDK-0.8.5

ygorelik commented 1 year ago

This is erroneous script, because by the time the function _build_bgp_instanceobj finished the top level object _bgp_operobj is released from memory by the Python garbage collector. That causes the script to crash.

The correct and working script would be:

#!/usr/bin/env python
#
from ydk.services import CRUDService
from ydk.providers import NetconfServiceProvider
from ydk.models.cisco_ios_xr import Cisco_IOS_XR_ipv4_bgp_oper as xr_ipv4_bgp_oper

import logging

def enable_logging(level):
    log = logging.getLogger('ydk')
    log.setLevel(level)
    handler = logging.StreamHandler()
    formatter = logging.Formatter(
            "%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    handler.setFormatter(formatter)
    log.addHandler(handler)

def build_bgp_instance_obj(bgp_oper_obj_):
    bgp_oper_instance_list_obj = xr_ipv4_bgp_oper.Bgp.Instances.Instance()
    bgp_oper_instance_list_obj.instance_name = "default"
    bgp_oper_obj_.instances.instance.append(bgp_oper_instance_list_obj)
    return bgp_oper_instance_list_obj

if __name__ == '__main__':

    enable_logging(logging.INFO)

    provider = NetconfServiceProvider(
        address='sbx-iosxr-mgmt.cisco.com',
        port=10000,
        username='admin',
        password='C1sco12345')

    crud = CRUDService()

    bgp_oper_obj = xr_ipv4_bgp_oper.Bgp()
    bgp_instance_obj = build_bgp_instance_obj(bgp_oper_obj)

    bgp_oper = crud.read(provider, bgp_instance_obj)
    if bgp_oper:
        print("Got BGP config")
    else:
        print("No BGP config found")

It produces this result:

2023-02-22 16:56:23,886 - ydk - INFO - Path where models are to be downloaded: /Users/ygorelik/.ydk/sbx-iosxr-mgmt.cisco.com
2023-02-22 16:56:23,898 - ydk - INFO - Connected to sbx-iosxr-mgmt.cisco.com on port 10000 using ssh with timeout of -1
2023-02-22 16:56:23,927 - ydk - INFO - Executing CRUD read operation on [Cisco-IOS-XR-ipv4-bgp-oper:bgp]
2023-02-22 16:56:23,927 - ydk - INFO - Executing 'get' RPC on [Cisco-IOS-XR-ipv4-bgp-oper:bgp]
2023-02-22 16:56:27,184 - ydk - INFO - ============= Sending RPC to device =============
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><get xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <filter><bgp xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-ipv4-bgp-oper">
  <instances>
    <instance>
      <instance-name>default</instance-name>
    </instance>
  </instances>
</bgp></filter>
</get>
</rpc>
No BGP config found
2023-02-22 16:56:28,425 - ydk - INFO - ============= Received RPC from device =============
<?xml version="1.0"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1">
  <data/>
</rpc-reply>

2023-02-22 16:56:28,426 - ydk - INFO - Found empty data tag, meaning requested data are not found on Netconf server
2023-02-22 16:56:28,470 - ydk - INFO - Disconnected from device