<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>