<p>Joshua Colp <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/13980">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Joshua Colp: Looks good to me, approved; Approved for Submit
  George Joseph: Looks good to me, but someone else must approve

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">ast_coredumper: add Asterisk information dump<br><br>This patch makes it so ast_coredumper now outputs the following information to<br>a *-info.txt file when processing a core file:<br><br>  asterisk version and "built by" string<br>  BUILD_OPTS<br>  system start, and last reloaded date/time<br>  taskprocessor list<br>  equivalent of "bridge show all"<br>  equivalent of "core show channels verbose"<br><br>Also a slight modification was made when trying to obtain the pid(s) of a<br>running Asterisk. If it fails to retrieve any it now reports an error.<br><br>Change-Id: I54f35c19ab69b8f8dc78cc933c3fb7c99cef346b<br>---<br>M contrib/scripts/ast_coredumper<br>1 file changed, 410 insertions(+), 7 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/contrib/scripts/ast_coredumper b/contrib/scripts/ast_coredumper</span><br><span>index defb629..ee62ab8 100755</span><br><span>--- a/contrib/scripts/ast_coredumper</span><br><span>+++ b/contrib/scripts/ast_coredumper</span><br><span>@@ -383,14 +383,9 @@</span><br><span>      unset pid</span><br><span> </span><br><span>        # Simplest case first...</span><br><span style="color: hsl(0, 100%, 40%);">-        pids=$(pgrep -f "$asterisk_bin")</span><br><span style="color: hsl(120, 100%, 40%);">+    pids=$(pgrep -f "$asterisk_bin" || : )</span><br><span>     pidcount=$(echo $pids | wc -w)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      if [ $pidcount -eq 0 ] ; then</span><br><span style="color: hsl(0, 100%, 40%);">-           >&2 echo "Asterisk is not running"</span><br><span style="color: hsl(0, 100%, 40%);">-             exit 1</span><br><span style="color: hsl(0, 100%, 40%);">-  fi</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>   # Single process, great.</span><br><span>     if [ $pidcount -eq 1 ] ; then</span><br><span>                pid=$pids</span><br><span>@@ -552,7 +547,7 @@</span><br><span>      fi</span><br><span> </span><br><span>       if $delete_results_after ; then</span><br><span style="color: hsl(0, 100%, 40%);">-         rm -rf "${cf//:/-}"-{brief,full,thread1,locks}.txt</span><br><span style="color: hsl(120, 100%, 40%);">+          rm -rf "${cf//:/-}"-{brief,full,thread1,locks,info}.txt</span><br><span>    fi</span><br><span> done</span><br><span> </span><br><span>@@ -568,12 +563,400 @@</span><br><span> </span><br><span> #@@@SCRIPTSTART@@@</span><br><span> python</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import datetime</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def timeval_to_datetime(value):</span><br><span style="color: hsl(120, 100%, 40%);">+    """Convert a timeval struct to a python datetime object</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    Args:</span><br><span style="color: hsl(120, 100%, 40%);">+        value: A gdb Value representing a C timeval</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    Return:</span><br><span style="color: hsl(120, 100%, 40%);">+        A python datetime object</span><br><span style="color: hsl(120, 100%, 40%);">+    """</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    sec = int(value['tv_sec'])</span><br><span style="color: hsl(120, 100%, 40%);">+    usec = int(value['tv_usec'])</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return datetime.datetime.fromtimestamp(sec + usec / float(1000000))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def s_strip(value):</span><br><span style="color: hsl(120, 100%, 40%);">+    """Convert the given value to a string, and strip any leading/trailing</span><br><span style="color: hsl(120, 100%, 40%);">+    spaces and/or quotes.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    Args:</span><br><span style="color: hsl(120, 100%, 40%);">+        name: The gdb Value to convert and strip</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    Return:</span><br><span style="color: hsl(120, 100%, 40%);">+        The stripped value as a string</span><br><span style="color: hsl(120, 100%, 40%);">+    """</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if value == None:</span><br><span style="color: hsl(120, 100%, 40%);">+        return "None"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    try:</span><br><span style="color: hsl(120, 100%, 40%);">+        if 'char *' not in str(value.type) and 'char [' not in str(value.type):</span><br><span style="color: hsl(120, 100%, 40%);">+            # Use the string method for everything but string pointers (only</span><br><span style="color: hsl(120, 100%, 40%);">+            # points to first letter) and non-string values in general</span><br><span style="color: hsl(120, 100%, 40%);">+            return value.string().strip('" ') or "<None>"</span><br><span style="color: hsl(120, 100%, 40%);">+    except:</span><br><span style="color: hsl(120, 100%, 40%);">+        pass</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return str(value).strip('" ') or "<None>"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def get(name):</span><br><span style="color: hsl(120, 100%, 40%);">+    """Retrieve a named variable's value as a string using GDB.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    Args:</span><br><span style="color: hsl(120, 100%, 40%);">+        name: The name of the variable to look up</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    Return:</span><br><span style="color: hsl(120, 100%, 40%);">+        The variable's value as a string</span><br><span style="color: hsl(120, 100%, 40%);">+    """</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return s_strip(gdb.parse_and_eval(name))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def get_container_hash_objects(name, type, on_object=None):</span><br><span style="color: hsl(120, 100%, 40%);">+    """Retrieve a list of objects from an ao2_container_hash.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    Expected on_object signature:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        res, stop = on_object(GDB Value)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    The given callback, on_object, is called for each object found in the</span><br><span style="color: hsl(120, 100%, 40%);">+    container. The callback is passed a dereferenced GDB Value object and</span><br><span style="color: hsl(120, 100%, 40%);">+    expects an object to be returned, which is then appended to a list of</span><br><span style="color: hsl(120, 100%, 40%);">+    objects to be returned by this function. Iteration can be stopped by</span><br><span style="color: hsl(120, 100%, 40%);">+    returning "True" for the second return value.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    If on_object is not specified then the dereferenced GDB value is instead</span><br><span style="color: hsl(120, 100%, 40%);">+    added directly to the returned list.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    Args:</span><br><span style="color: hsl(120, 100%, 40%);">+        name: The name of the ao2_container</span><br><span style="color: hsl(120, 100%, 40%);">+        type: The type of objects stored in the container</span><br><span style="color: hsl(120, 100%, 40%);">+        on_object: Optional function called on each object found</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    Return:</span><br><span style="color: hsl(120, 100%, 40%);">+        A list of container objects</span><br><span style="color: hsl(120, 100%, 40%);">+    """</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    objs = []</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    try:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        container = gdb.parse_and_eval(name).cast(</span><br><span style="color: hsl(120, 100%, 40%);">+            gdb.lookup_type('struct ao2_container_hash').pointer())</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        # Loop over every bucket searching for hash bucket nodes</span><br><span style="color: hsl(120, 100%, 40%);">+        for n in range(container['n_buckets']):</span><br><span style="color: hsl(120, 100%, 40%);">+            node = container['buckets'][n]['list']['last']</span><br><span style="color: hsl(120, 100%, 40%);">+            while node:</span><br><span style="color: hsl(120, 100%, 40%);">+                # Each node holds the needed object</span><br><span style="color: hsl(120, 100%, 40%);">+                obj = node.dereference()['common']['obj'].cast(</span><br><span style="color: hsl(120, 100%, 40%);">+                    gdb.lookup_type(type).pointer()).dereference()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                res, stop = on_object(obj) if on_object else (obj, False)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                if res:</span><br><span style="color: hsl(120, 100%, 40%);">+                    objs.append(res)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                if stop:</span><br><span style="color: hsl(120, 100%, 40%);">+                    return objs</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                node = node.dereference()['links']['last']</span><br><span style="color: hsl(120, 100%, 40%);">+    except Exception as e:</span><br><span style="color: hsl(120, 100%, 40%);">+        print("{0} - {1}".format(name, e))</span><br><span style="color: hsl(120, 100%, 40%);">+        pass</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return objs</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def get_container_rbtree_objects(name, type, on_object=None):</span><br><span style="color: hsl(120, 100%, 40%);">+    """Retrieve a list of objects from an ao2_container_rbtree.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    Expected on_object signature:</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        res, stop = on_object(GDB Value)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    The given callback, on_object, is called for each object found in the</span><br><span style="color: hsl(120, 100%, 40%);">+    container. The callback is passed a dereferenced GDB Value object and</span><br><span style="color: hsl(120, 100%, 40%);">+    expects an object to be returned, which is then appended to a list of</span><br><span style="color: hsl(120, 100%, 40%);">+    objects to be returned by this function. Iteration can be stopped by</span><br><span style="color: hsl(120, 100%, 40%);">+    returning "True" for the second return value.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    If on_object is not specified then the dereferenced GDB value is instead</span><br><span style="color: hsl(120, 100%, 40%);">+    added directly to the returned list.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    Args:</span><br><span style="color: hsl(120, 100%, 40%);">+        name: The name of the ao2_container</span><br><span style="color: hsl(120, 100%, 40%);">+        type: The type of objects stored in the container</span><br><span style="color: hsl(120, 100%, 40%);">+        on_object: Optional function called on each object found</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    Return:</span><br><span style="color: hsl(120, 100%, 40%);">+        A list of container objects</span><br><span style="color: hsl(120, 100%, 40%);">+    """</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    objs = []</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def handle_node(node):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if not node:</span><br><span style="color: hsl(120, 100%, 40%);">+            return True</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        # Each node holds the needed object</span><br><span style="color: hsl(120, 100%, 40%);">+        obj = node.dereference()['common']['obj'].cast(</span><br><span style="color: hsl(120, 100%, 40%);">+            gdb.lookup_type(type).pointer()).dereference()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        res, stop = on_object(obj) if on_object else (obj, False)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if res:</span><br><span style="color: hsl(120, 100%, 40%);">+            objs.append(res)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return not stop and (handle_node(node['left']) and</span><br><span style="color: hsl(120, 100%, 40%);">+                             handle_node(node['right']))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    try:</span><br><span style="color: hsl(120, 100%, 40%);">+        container = gdb.parse_and_eval(name).cast(</span><br><span style="color: hsl(120, 100%, 40%);">+            gdb.lookup_type('struct ao2_container_rbtree').pointer())</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        handle_node(container['root'])</span><br><span style="color: hsl(120, 100%, 40%);">+    except Exception as e:</span><br><span style="color: hsl(120, 100%, 40%);">+        print("{0} - {1}".format(name, e))</span><br><span style="color: hsl(120, 100%, 40%);">+        pass</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return objs</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def build_info():</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    try:</span><br><span style="color: hsl(120, 100%, 40%);">+        return ("Asterisk {0} built by {1} @ {2} on a {3} running {4} on {5}"</span><br><span style="color: hsl(120, 100%, 40%);">+                .format(get("asterisk_version"),</span><br><span style="color: hsl(120, 100%, 40%);">+                    get("ast_build_user"),</span><br><span style="color: hsl(120, 100%, 40%);">+                    get("ast_build_hostname"),</span><br><span style="color: hsl(120, 100%, 40%);">+                    get("ast_build_machine"),</span><br><span style="color: hsl(120, 100%, 40%);">+                    get("ast_build_os"),</span><br><span style="color: hsl(120, 100%, 40%);">+                    get("ast_build_date")))</span><br><span style="color: hsl(120, 100%, 40%);">+    except:</span><br><span style="color: hsl(120, 100%, 40%);">+        return "Unable to retrieve build info"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def build_opts():</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    try:</span><br><span style="color: hsl(120, 100%, 40%);">+        return get("asterisk_build_opts")</span><br><span style="color: hsl(120, 100%, 40%);">+    except:</span><br><span style="color: hsl(120, 100%, 40%);">+        return "Unable to retrieve build options"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def uptime():</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    try:</span><br><span style="color: hsl(120, 100%, 40%);">+        started = timeval_to_datetime(gdb.parse_and_eval("ast_startuptime"))</span><br><span style="color: hsl(120, 100%, 40%);">+        loaded = timeval_to_datetime(gdb.parse_and_eval("ast_lastreloadtime"))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return ("System started: {0}\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                "Last reload: {1}".format(started, loaded))</span><br><span style="color: hsl(120, 100%, 40%);">+    except:</span><br><span style="color: hsl(120, 100%, 40%);">+        return "Unable to retrieve uptime"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+class TaskProcessor(object):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    template = ("{name:70} {processed:>10} {in_queue:>10} {max_depth:>10} "</span><br><span style="color: hsl(120, 100%, 40%);">+                "{low_water:>10} {high_water:>10}")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    header = {'name': 'Processor', 'processed': 'Processed',</span><br><span style="color: hsl(120, 100%, 40%);">+              'in_queue': 'In Queue', 'max_depth': 'Max Depth',</span><br><span style="color: hsl(120, 100%, 40%);">+              'low_water': 'Low water', 'high_water': 'High water'}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    @staticmethod</span><br><span style="color: hsl(120, 100%, 40%);">+    def objects():</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        try:</span><br><span style="color: hsl(120, 100%, 40%);">+            objs = get_container_hash_objects('tps_singletons',</span><br><span style="color: hsl(120, 100%, 40%);">+                'struct ast_taskprocessor', TaskProcessor.from_value)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            objs.sort(key=lambda x: x.name.lower())</span><br><span style="color: hsl(120, 100%, 40%);">+        except Exception as e:</span><br><span style="color: hsl(120, 100%, 40%);">+            return []</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return objs</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    @staticmethod</span><br><span style="color: hsl(120, 100%, 40%);">+    def from_value(value):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return TaskProcessor(</span><br><span style="color: hsl(120, 100%, 40%);">+            value['name'],</span><br><span style="color: hsl(120, 100%, 40%);">+            value['stats']['_tasks_processed_count'],</span><br><span style="color: hsl(120, 100%, 40%);">+            value['tps_queue_size'],</span><br><span style="color: hsl(120, 100%, 40%);">+            value['stats']['max_qsize'],</span><br><span style="color: hsl(120, 100%, 40%);">+            value['tps_queue_low'],</span><br><span style="color: hsl(120, 100%, 40%);">+            value['tps_queue_high']), False</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def __init__(self, name, processed, in_queue, max_depth,</span><br><span style="color: hsl(120, 100%, 40%);">+                 low_water, high_water):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        self.name = s_strip(name)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.processed = int(processed)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.in_queue = int(in_queue)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.max_depth = int(max_depth)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.low_water = int(low_water)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.high_water = int(high_water)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+class Channel(object):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    template = ("{name:30} {context:>20} {exten:>20} {priority:>10} {state:>25} "</span><br><span style="color: hsl(120, 100%, 40%);">+                "{app:>20} {data:>30} {caller_id:>15} {created:>30} "</span><br><span style="color: hsl(120, 100%, 40%);">+                "{account_code:>15} {peer_account:>15} {bridge_id:>38}")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    header = {'name': 'Channel', 'context': 'Context', 'exten': 'Extension',</span><br><span style="color: hsl(120, 100%, 40%);">+              'priority': 'Priority', 'state': "State", 'app': 'Application',</span><br><span style="color: hsl(120, 100%, 40%);">+              'data': 'Data', 'caller_id': 'CallerID', 'created': 'Created',</span><br><span style="color: hsl(120, 100%, 40%);">+              'account_code': 'Accountcode', 'peer_account': 'PeerAccount',</span><br><span style="color: hsl(120, 100%, 40%);">+              'bridge_id': 'BridgeID'}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    @staticmethod</span><br><span style="color: hsl(120, 100%, 40%);">+    def objects():</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        try:</span><br><span style="color: hsl(120, 100%, 40%);">+            objs = get_container_hash_objects('channels',</span><br><span style="color: hsl(120, 100%, 40%);">+                'struct ast_channel', Channel.from_value)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            objs.sort(key=lambda x: x.name.lower())</span><br><span style="color: hsl(120, 100%, 40%);">+        except:</span><br><span style="color: hsl(120, 100%, 40%);">+            return []</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return objs</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    @staticmethod</span><br><span style="color: hsl(120, 100%, 40%);">+    def from_value(value):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        bridge_id = None</span><br><span style="color: hsl(120, 100%, 40%);">+        if value['bridge']:</span><br><span style="color: hsl(120, 100%, 40%);">+            bridge_id = value['bridge']['uniqueid']</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return Channel(</span><br><span style="color: hsl(120, 100%, 40%);">+            value['name'],</span><br><span style="color: hsl(120, 100%, 40%);">+            value['context'],</span><br><span style="color: hsl(120, 100%, 40%);">+            value['exten'],</span><br><span style="color: hsl(120, 100%, 40%);">+            value['priority'],</span><br><span style="color: hsl(120, 100%, 40%);">+            value['state'],</span><br><span style="color: hsl(120, 100%, 40%);">+            value['appl'],</span><br><span style="color: hsl(120, 100%, 40%);">+            value['data'],</span><br><span style="color: hsl(120, 100%, 40%);">+            value['caller']['id']['number']['str'],</span><br><span style="color: hsl(120, 100%, 40%);">+            timeval_to_datetime(value['creationtime']),</span><br><span style="color: hsl(120, 100%, 40%);">+            value['accountcode'],</span><br><span style="color: hsl(120, 100%, 40%);">+            value['peeraccount'],</span><br><span style="color: hsl(120, 100%, 40%);">+            bridge_id), False</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    @staticmethod</span><br><span style="color: hsl(120, 100%, 40%);">+    def summary():</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        try:</span><br><span style="color: hsl(120, 100%, 40%);">+            return ("{0} active channels\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                    "{1} active calls\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                    "{2} calls processed".format(</span><br><span style="color: hsl(120, 100%, 40%);">+                        int(gdb.parse_and_eval(</span><br><span style="color: hsl(120, 100%, 40%);">+                            'channels').dereference()['elements']),</span><br><span style="color: hsl(120, 100%, 40%);">+                        get("countcalls"),</span><br><span style="color: hsl(120, 100%, 40%);">+                        get("totalcalls")))</span><br><span style="color: hsl(120, 100%, 40%);">+        except:</span><br><span style="color: hsl(120, 100%, 40%);">+            return "Unable to retrieve channel summary"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def __init__(self, name, context=None, exten=None, priority=None,</span><br><span style="color: hsl(120, 100%, 40%);">+                 state=None, app=None, data=None, caller_id=None,</span><br><span style="color: hsl(120, 100%, 40%);">+                 created=None, account_code=None, peer_account=None,</span><br><span style="color: hsl(120, 100%, 40%);">+                 bridge_id=None):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        self.name = s_strip(name)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.context = s_strip(context)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.exten = s_strip(exten)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.priority = int(priority)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.state = s_strip(state)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.app = s_strip(app)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.data = s_strip(data)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.caller_id = s_strip(caller_id)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.created = s_strip(created)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.account_code = s_strip(account_code)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.peer_account = s_strip(peer_account)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.bridge_id = s_strip(bridge_id)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+class Bridge(object):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    template = ("{uniqueid:38} {num_channels:>15} {subclass:>10} {tech:>20} "</span><br><span style="color: hsl(120, 100%, 40%);">+                "{created:>30}")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    header = {'uniqueid': 'Bridge-ID', 'num_channels': 'Chans',</span><br><span style="color: hsl(120, 100%, 40%);">+              'subclass': 'Type', 'tech': 'Technology', 'created': 'Created'}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    @staticmethod</span><br><span style="color: hsl(120, 100%, 40%);">+    def objects():</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        try:</span><br><span style="color: hsl(120, 100%, 40%);">+            objs = get_container_rbtree_objects('bridges',</span><br><span style="color: hsl(120, 100%, 40%);">+                'struct ast_bridge', Bridge.from_value)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            objs.sort(key=lambda x: x.uniqueid.lower())</span><br><span style="color: hsl(120, 100%, 40%);">+        except:</span><br><span style="color: hsl(120, 100%, 40%);">+            return []</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return objs</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    @staticmethod</span><br><span style="color: hsl(120, 100%, 40%);">+    def from_value(value):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return Bridge(</span><br><span style="color: hsl(120, 100%, 40%);">+            value['uniqueid'],</span><br><span style="color: hsl(120, 100%, 40%);">+            value['num_channels'],</span><br><span style="color: hsl(120, 100%, 40%);">+            timeval_to_datetime(value['creationtime']),</span><br><span style="color: hsl(120, 100%, 40%);">+            value['v_table']['name'],</span><br><span style="color: hsl(120, 100%, 40%);">+            value['technology']['name']), False</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    def __init__(self, uniqueid, num_channels=None, created=None, subclass=None,</span><br><span style="color: hsl(120, 100%, 40%);">+                 tech=None):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        self.uniqueid = s_strip(uniqueid)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.num_channels = int(num_channels)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.created = s_strip(created)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.subclass = s_strip(subclass)</span><br><span style="color: hsl(120, 100%, 40%);">+        self.tech = s_strip(tech)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> class DumpAsteriskCommand(gdb.Command):</span><br><span> </span><br><span>     def __init__(self):</span><br><span>         super(DumpAsteriskCommand, self).__init__ ("dump-asterisk",</span><br><span>             gdb.COMMAND_OBSCURE, gdb.COMPLETE_COMMAND)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+    def print_table(self, type):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        plural = "{0}s".format(type.__name__)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        objs = type.objects()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if not len(objs):</span><br><span style="color: hsl(120, 100%, 40%);">+            print("{0} not found\n".format(plural))</span><br><span style="color: hsl(120, 100%, 40%);">+            return</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        print("{0} ({1}):\n".format(plural, len(objs)))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        print(type.template.format(**type.header))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        for obj in objs:</span><br><span style="color: hsl(120, 100%, 40%);">+            print(type.template.format(**vars(obj)))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        print("\n")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     def invoke(self, arg, from_tty):</span><br><span>         try:</span><br><span>             gdb.execute("interrupt", from_tty)</span><br><span>@@ -619,6 +1002,26 @@</span><br><span>             gdb.execute("show_locks", from_tty)</span><br><span>         except:</span><br><span>             pass</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        print("!@!@!@! info.txt !@!@!@!\n")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        gdb.execute('set print addr off')</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        try:</span><br><span style="color: hsl(120, 100%, 40%);">+            print("{0}\n".format(build_info()))</span><br><span style="color: hsl(120, 100%, 40%);">+            print("{0}\n".format(uptime()))</span><br><span style="color: hsl(120, 100%, 40%);">+            print("Build options = {0}\n".format(build_opts()))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            self.print_table(TaskProcessor)</span><br><span style="color: hsl(120, 100%, 40%);">+            self.print_table(Bridge)</span><br><span style="color: hsl(120, 100%, 40%);">+            self.print_table(Channel)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            print(Channel.summary())</span><br><span style="color: hsl(120, 100%, 40%);">+        except:</span><br><span style="color: hsl(120, 100%, 40%);">+            pass</span><br><span style="color: hsl(120, 100%, 40%);">+        finally:</span><br><span style="color: hsl(120, 100%, 40%);">+            gdb.execute('set print addr on')</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         try:</span><br><span>             gdb.execute("continue", from_tty)</span><br><span>         except:</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/13980">change 13980</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/13980"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 17 </div>
<div style="display:none"> Gerrit-Change-Id: I54f35c19ab69b8f8dc78cc933c3fb7c99cef346b </div>
<div style="display:none"> Gerrit-Change-Number: 13980 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>