summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2015-03-17 13:11:57 +1100
committerChris Johns <chrisj@rtems.org>2015-03-17 13:12:15 +1100
commitb117be8e1faeb5e672d63449635957950cb7b2ba (patch)
treece859074e5164912f67cc11ad53bb955e40ee98b
parentAdd configurations for all h8 GDB simulator BSP variants (diff)
downloadrtems-tools-b117be8e1faeb5e672d63449635957950cb7b2ba.tar.bz2
gdb/python: Update the support to a recent RTEMS.
-rw-r--r--tools/gdb/python/chains.py35
-rw-r--r--tools/gdb/python/classic.py111
-rw-r--r--tools/gdb/python/mutex.py128
-rw-r--r--tools/gdb/python/rbtrees.py163
-rw-r--r--tools/gdb/python/rtems.py24
-rw-r--r--tools/gdb/python/threads.py57
-rw-r--r--tools/gdb/python/time.py79
7 files changed, 512 insertions, 85 deletions
diff --git a/tools/gdb/python/chains.py b/tools/gdb/python/chains.py
index 6ae2518..58a354a 100644
--- a/tools/gdb/python/chains.py
+++ b/tools/gdb/python/chains.py
@@ -37,7 +37,18 @@ class node:
"""Manage the Chain_Node."""
def __init__(self, node_val):
- self.node_val = node_val
+ if node_val:
+ if node_val.type.code == gdb.TYPE_CODE_PTR:
+ self.reference = node_val
+ self.node_val = node_val.dereference()
+ else:
+ self.node_val = node_val
+ self.reference = node_val.address
+ else:
+ self.node_val = node_val
+
+ def __str__(self):
+ return self.to_string()
def null(self):
if not self.node_val:
@@ -46,11 +57,11 @@ class node:
def next(self):
if not self.null():
- self.node_val = self.node_val['next']
+ return self.node_val['next']
def previous(self):
if not self.null():
- self.node_val = self.node_val['previous']
+ return self.node_val['previous']
def cast(self, typename):
if not self.null():
@@ -59,21 +70,31 @@ class node:
return None
def to_string(self):
- return self.node_val['next'] + "Prev: "+self.node_val['previous']
+ if self.null():
+ return 'NULL'
+ return 'Node:%s Next:%s Prev:%s' % (self.reference,
+ self.node_val['next'],
+ self.node_val['previous'])
class control:
"""Manage the Chain_Control."""
def __init__(self, ctrl):
- self.ctrl = ctrl
+ if ctrl.type.code == gdb.TYPE_CODE_PTR:
+ self.reference = ctrl
+ self.ctrl = ctrl.dereference()
+ else:
+ self.ctrl = ctrl
+ self.reference = ctrl.address
def first(self):
t = node(self.ctrl['Head']['Node'])
return t
- def last(self):
+ def tail(self):
return node(self.ctrl['Tail']['Node'])
def empty(self):
- if self.last() == self.first().next():
+ if self.tail().previous() == self.reference:
return True
+ return False
diff --git a/tools/gdb/python/classic.py b/tools/gdb/python/classic.py
index 44a92b4..7c004db 100644
--- a/tools/gdb/python/classic.py
+++ b/tools/gdb/python/classic.py
@@ -37,11 +37,12 @@ import re
#ToDo This shouldn't be here
import helper
+import heaps
+import mutex
import objects
+import supercore
import threads
import watchdog
-import heaps
-import supercore
class attribute:
"""The Classic API attribute."""
@@ -111,7 +112,7 @@ class attribute:
#ToDo: Move this out
def to_string(self):
- s = '0x%08x,' % (self.attr)
+ s = '(0x%08x) ' % (self.attr)
if self.attrtype != 'none':
for m in self.groups[self.attrtype]:
v = self.attr & self.masks[m]
@@ -135,44 +136,42 @@ class semaphore:
"Print a classic semaphore."
def __init__(self, obj):
- self.reference = obj
- self.object = obj.dereference()
+ if obj.type.code == gdb.TYPE_CODE_PTR:
+ self.reference = obj
+ self.object = obj.dereference()
+ else:
+ self.object = obj
+ self.reference = obj.address
self.object_control = objects.control(self.object['Object'])
self.attr = attribute(self.object['attribute_set'], 'semaphore')
def show(self, from_tty):
- print ' Name:', self.object_control.name()
- print ' Attr:', self.attr.to_string()
- if self.attr.test('semaphore-type', 'bin-sema') or \
- self.attr.test('semaphore-type', 'simple-bin-sema'):
- core_mutex = self.object['Core_control']['mutex']
- locked = core_mutex['lock'] == 0
- if locked:
- s = 'locked'
- else:
- s = 'unlocked'
- print ' Lock:', s
- print ' Nesting:', core_mutex['nest_count']
- print ' Blocked:', core_mutex['blocked_count']
- print ' Holder:',
- holder = core_mutex['holder']
- if holder and locked:
- holder = threads.control(holder.dereference())
- print holder.brief()
- elif holder == 0 and locked:
- print 'locked but no holder'
- else:
- print 'unlocked'
- wait_queue = threads.queue(core_mutex['Wait_queue'])
- tasks = wait_queue.tasks()
- print ' Queue: len = %d, state = %s' % (len(tasks),
- wait_queue.state())
- print ' Tasks:'
- print ' Name (c:current, r:real), (id)'
- for t in range(0, len(tasks)):
- print ' ', tasks[t].brief(), ' (%08x)' % (tasks[t].id())
- else:
- print 'semaphore'
+ if self.object_control.id() != 0:
+ print ' Name:', self.object_control.name()
+ print ' Id: 0x%08x (@ 0x%08x)' % (self.object_control.id(),
+ self.reference)
+ print ' Attr:', self.attr.to_string()
+ if self.attr.test('semaphore-type', 'bin-sema') or \
+ self.attr.test('semaphore-type', 'simple-bin-sema'):
+ core_mutex = mutex.control(self.object['Core_control']['mutex'])
+ print ' Nesting:', core_mutex.nest_count()
+ print ' Holder:',
+ holder = core_mutex.holder()
+ if holder:
+ print '%s (id 0x%08x)' % (holder.brief(), holder.id())
+ else:
+ print 'no holder (unlocked)'
+ wait_queue = core_mutex.wait_queue()
+ tasks = wait_queue.tasks()
+ print ' Queue: len = %d, state = %s' % (len(tasks),
+ wait_queue.state())
+ if len(tasks) > 0:
+ print ' Tasks:'
+ print ' Name (c:current, r:real), (id)'
+ for t in range(0, len(tasks)):
+ print ' ', tasks[t].brief(), ' (%08x)' % (tasks[t].id())
+ return True
+ return False
class task:
"Print a classic task"
@@ -186,23 +185,27 @@ class task:
#self.regs = sparc.register(self.object['Registers'])
def show(self, from_tty):
- cpu = self.task.executing()
- if cpu == -1:
- cpu = 'not executing'
- print ' Id:', '0x%08x' % (self.task.id())
- print ' Name:', self.task.name()
- print ' Active CPU:', cpu
- print ' State:', self.task.current_state()
- print ' Current:', self.task.current_priority()
- print ' Real:', self.task.real_priority()
- print ' Preempt:', self.task.preemptible()
- print ' T Budget:', self.task.cpu_time_budget()
- print ' Time:', self.task.cpu_time_used()
- print ' Resources:', self.task.resource_count()
- print ' Regsters:'
- for name in self.regs.names():
- val = self.regs.get(name)
- print ' %20s: %08x (%d)' % (name, val, val)
+ if self.task.id() != 0:
+ cpu = self.task.executing()
+ if cpu == -1:
+ cpu = 'not executing'
+ print ' Id:', '0x%08x (@ 0x%08x)' % (self.task.id(),
+ self.task.reference)
+ print ' Name:', self.task.name()
+ print ' Active CPU:', cpu
+ print ' State:', self.task.current_state()
+ print ' Current:', self.task.current_priority()
+ print ' Real:', self.task.real_priority()
+ print ' Preempt:', self.task.preemptible()
+ print ' T Budget:', self.task.cpu_time_budget()
+ print ' Time:', self.task.cpu_time_used()
+ print ' Resources:', self.task.resource_count()
+ print ' Regsters:'
+ for name in self.regs.names():
+ val = self.regs.get(name)
+ print ' %20s: %08x (%d)' % (name, val, val)
+ return True
+ return False
class message_queue:
"Print classic messege queue"
diff --git a/tools/gdb/python/mutex.py b/tools/gdb/python/mutex.py
new file mode 100644
index 0000000..17f1900
--- /dev/null
+++ b/tools/gdb/python/mutex.py
@@ -0,0 +1,128 @@
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010-2015 Chris Johns (chrisj@rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# RTEMS Mutex Support
+#
+
+import gdb
+
+import objects
+import percpu
+import threads
+
+class attributes:
+ CORE_MUTEX_NESTING_ACQUIRES = 0
+ CORE_MUTEX_NESTING_IS_ERROR = 1
+ CORE_MUTEX_NESTING_BLOCKS = 2
+
+ CORE_MUTEX_DISCIPLINES_FIFO = 0
+ CORE_MUTEX_DISCIPLINES_PRIORITY = 1
+ CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT = 2
+ CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING = 3
+
+ def __init__(self, attr):
+ self.attr = attr
+
+ def lock_nesting_behaviour(self):
+ return self.attr['lock_nesting_behaviour']
+
+ def only_owner_release(self):
+ return self.attr['only_owner_release']
+
+ def discipline(self):
+ return self.attr['discipline']
+
+ def priority_ceiling(self):
+ return self.attr['priority_ceiling']
+
+ def brief(self):
+ s = ''
+ if self.lock_nesting_behaviour() == CORE_MUTEX_NESTING_ACQUIRES:
+ s += 'lck-nest-acquire'
+ elif self.lock_nesting_behaviour() == CORE_MUTEX_NESTING_IS_ERROR:
+ s += 'lck-nest-acquire'
+ elif self.lock_nesting_behaviour() == CORE_MUTEX_NESTING_BLOCKS:
+ s += 'lck-nest-blocks'
+ else:
+ s += 'lck-nest-bad'
+ if self.only_owner_release():
+ s += ',owner-release'
+ else:
+ s += ',any-release'
+ if self.discipline() == CORE_MUTEX_DISCIPLINES_FIFO:
+ s += ',fifo'
+ elif self.discipline() == CORE_MUTEX_DISCIPLINES_PRIORITY:
+ s += ',pri'
+ elif self.discipline() == CORE_MUTEX_DISCIPLINES_INHERIT:
+ s += ',inherit'
+ elif self.discipline() == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
+ s += ',pri-celling'
+ else:
+ s += ',dis-bad'
+ return s
+
+class control():
+ '''
+ CORE_mutex_Control has the following fields:
+ Wait_queue Thread_queue_Control
+ Attributes CORE_mutex_attributes
+ nest_count uint32_t
+ *holder Thread_control
+ queue CORE_mutex_order_list X
+
+ where 'X' means the field is condition and may no exist.
+ '''
+
+ def __init__(self, ctrl):
+ if ctrl.type.code == gdb.TYPE_CODE_PTR:
+ self.reference = ctrl
+ self.ctrl = ctrl.dereference()
+ else:
+ self.ctrl = ctrl
+ self.reference = ctrl.address
+ self.attr = attributes(ctrl['Attributes'])
+
+ def wait_queue(self):
+ return threads.queue(self.ctrl['Wait_queue'])
+
+ def attributes(self):
+ return self.attr
+
+ def nest_count(self):
+ return self.ctrl['nest_count']
+
+ def holder(self):
+ h = self.ctrl['holder']
+ if h:
+ return threads.control(h)
+ return None
+
+ def brief(self):
+ return "nests:%d, %s" % (self.ctrl['nest_count'], self.attr.brief())
diff --git a/tools/gdb/python/rbtrees.py b/tools/gdb/python/rbtrees.py
new file mode 100644
index 0000000..2e4c9e7
--- /dev/null
+++ b/tools/gdb/python/rbtrees.py
@@ -0,0 +1,163 @@
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010-2015 Chris Johns (chrisj@rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# RTEMS Red/Black Tree Support
+#
+
+import gdb
+
+rbt_left = 0
+rbt_right = 1
+
+def opp_dir(dir_):
+ if dir_ == rbt_left:
+ return rbt_right
+ return rbt_left
+
+
+class node:
+ """Manage the RBTree_Node_struct."""
+
+ def __init__(self, node_ptr):
+ self.node_ptr = node_ptr
+ self.node_val = None
+ if node_ptr != 0:
+ print '}}}}'
+ self.node_val = node_ptr.dereference()
+
+ def __str__(self):
+ return self.to_string()
+
+ def null(self):
+ if not self.node_val:
+ return True
+ return False
+
+ def pointer(self):
+ return self.node_ptr
+
+ def parent(self):
+ if not self.null():
+ return self.node_val['parent']
+ return None
+
+ def child(self):
+ if not self.null():
+ return self.node_val['child']
+ return None
+
+ def left(self):
+ if not self.null():
+ return self.node_val['child'][rbt_left]
+ return None
+
+ def right(self):
+ if not self.null():
+ return self.node_val['child'][rbt_right]
+ return None
+
+ def next(self, dir_):
+ next_ = None
+ if not self.null():
+ current = self.child(color, dir_)
+ if current is not None:
+ while current is not None:
+ cn = node(current)
+ current = cn.child(opp_dir(dir_))
+ next_ = current
+ else:
+ # RBTree_Node *parent = node->parent;
+ # if ( parent->parent && node == parent->child[ opp_dir ] ) {
+ #
+ # node->parent
+ if self.parent():
+ # pn = *(node->parent) or pn = *parent
+ pn = node(self.parent())
+ if pn.parent() and (self.pointer() == pn.child(opp_dir(dir_))):
+ next_ = self.parent()
+ else:
+ nn = self
+ while pn.parent():
+ if nn.pointer() != pn.child(dir_):
+ break
+ nn = pn
+ pn = node(pn.parent())
+ if pn.parent():
+ next_ = pn.pointer()
+ return next_
+
+ def predecessor(self):
+ return self.next(rbt_left)
+
+ def successor(self):
+ return self.next(rbt_right)
+
+ def color(self):
+ if not self.null():
+ return self.node_val['color']
+ return None
+
+ def cast(self, typename):
+ if not self.null():
+ nodetype = gdb.lookup_type(typename)
+ return self.node_val.cast(nodetype)
+ return None
+
+ def off_tree(self):
+ if parent.null():
+ return True
+ return False
+
+ def to_string(self):
+ if self.null():
+ return 'NULL'
+ print ']]] here'
+ return 'Parent:%s Child:%s Color:%s' % (self.node_val['parent'],
+ self.node_val['child'],
+ self.node_val['color'])
+
+class control:
+ """Manage the RBTree_Control."""
+
+ def __init__(self, ctrl):
+ self.ctrl = ctrl
+
+ def root(self):
+ """Return the root node of the RBT."""
+ return node(self.ctrl['root'])
+
+ def first(self, dir_):
+ """ Return the min or max nodes of this RBT."""
+ return node(self.ctrl['first'][dir_])
+
+ def empty(self):
+ if self.root().null():
+ return True
+ return False
diff --git a/tools/gdb/python/rtems.py b/tools/gdb/python/rtems.py
index 534cb0d..d4317ff 100644
--- a/tools/gdb/python/rtems.py
+++ b/tools/gdb/python/rtems.py
@@ -72,17 +72,18 @@ class rtems_object(gdb.Command):
gdb.COMPLETE_SYMBOL)
def invoke(self, arg, from_tty):
+ vald = False
for num in arg.split():
try:
val = gdb.parse_and_eval(num)
num = int(val)
except:
print 'error: "%s" is not a number' % (num)
- return
+ return True
id = objects.ident(num)
if not id.valid():
print 'Invalid object id'
- return
+ return True
print 'API:%s Class:%s Node:%d Index:%d Id:%08X' % \
(id.api(), id._class(), id.node(), id.index(), id.value())
@@ -91,8 +92,9 @@ class rtems_object(gdb.Command):
obj = objects.information.object(id).dereference()
if objectname in self.objects:
object = self.objects[objectname](obj)
- object.show(from_tty)
+ valid = object.show(from_tty)
objects.information.invalidate()
+ return valid
class rtems_index(gdb.Command):
'''Print object by index'''
@@ -113,8 +115,9 @@ class rtems_index(gdb.Command):
def invoke(self, arg, from_tty):
maximum = objects.information.maximum(self.api, self._class)
minimum_id = objects.ident(objects.information.minimum_id(self.api, self._class))
- maximum_id = objects.ident(objects.information.minimum_id(self.api, self._class))
+ maximum_id = objects.ident(objects.information.maximum_id(self.api, self._class))
args = arg.split()
+ valid = False
if len(args):
for val in args:
try:
@@ -137,15 +140,18 @@ class rtems_index(gdb.Command):
print "error: index %s is invalid" % (index)
return
instance = self.instance(obj)
- instance.show(from_tty)
+ valid = instance.show(from_tty)
objects.information.invalidate()
else:
print '-' * 70
print ' %s: %d [%08x -> %08x]' % (objects.information.name(self.api, self._class),
maximum, minimum_id.value(), maximum_id.value())
+ valid = True
for index in range(minimum_id.index(), minimum_id.index() + maximum):
- print '-' * 70
- self.invoke(str(index), from_tty)
+ if valid:
+ print '-' * 70
+ valid = self.invoke(str(index), from_tty)
+ return valid
class rtems_semaphore(rtems_index):
'''semaphore subcommand'''
@@ -242,11 +248,9 @@ class rtems_tod(gdb.Command):
('rtems tod', gdb.COMMAND_STATUS,gdb.COMPLETE_NONE)
def invoke(self, arg, from_tty):
-
if arg:
print "warning: commad takes no arguments!"
-
- obj = objects.information.object_return(self.api,self._class)
+ obj = objects.information.object_return(self.api, self._class)
instance = supercore.time_of_day(obj)
instance.show()
objects.information.invalidate()
diff --git a/tools/gdb/python/threads.py b/tools/gdb/python/threads.py
index 1719187..690f77f 100644
--- a/tools/gdb/python/threads.py
+++ b/tools/gdb/python/threads.py
@@ -1,5 +1,5 @@
# RTEMS Tools Project (http://www.rtems.org/)
-# Copyright 2010-2014 Chris Johns (chrisj@rtems.org)
+# Copyright 2010-2015 Chris Johns (chrisj@rtems.org)
# All rights reserved.
#
# This file is part of the RTEMS Tools package in 'rtems-tools'.
@@ -36,13 +36,25 @@ import gdb
import chains
import objects
import percpu
+import rbtrees
+import time
def task_chain(chain):
tasks = []
- node = chain.first()
+ if not chain.empty():
+ node = chain.first()
+ while not node.null():
+ t = control(node.cast('Thread_Control'))
+ tasks.append(t)
+ node = node(node.next())
+ return tasks
+
+def task_tree(tree):
+ tasks = []
+ node = tree.first(rbtrees.rbt_left)
while not node.null():
tasks.append(control(node.cast('Thread_Control')))
- node.next()
+ node = node.next(rbtrees.rbt_left)
return tasks
class state():
@@ -128,6 +140,17 @@ class state():
s = self.masks[m] + ','
return s[:-1]
+class cpu_usage():
+
+ def __init__(self, time_):
+ self.time = time.time(time_)
+
+ def __str__(self):
+ return self.time.tostring()
+
+ def get(self):
+ return self.time.get()
+
class wait_info():
def __init__(self, info):
@@ -165,7 +188,6 @@ class registers():
return float(self.regs[reg])
return int(self.regs[reg])
-
def format(self, reg):
t = self.regs[reg].type
if t in ['uint32_t', 'unsigned', 'unsigned long']:
@@ -208,8 +230,12 @@ class control():
'''
def __init__(self, ctrl):
- self.reference = ctrl
- self.ctrl = ctrl.dereference()
+ if ctrl.type.code == gdb.TYPE_CODE_PTR:
+ self.reference = ctrl
+ self.ctrl = ctrl.dereference()
+ else:
+ self.ctrl = ctrl
+ self.reference = ctrl.address
self.object = objects.control(ctrl['Object'])
self._executing = percpu.thread_active(self.reference)
self._heir = percpu.thread_heir(self.reference)
@@ -245,7 +271,7 @@ class control():
return self.ctrl['cpu_time_budget']
def cpu_time_used(self):
- return self.ctrl['cpu_time_used']
+ return cpu_usage(self.ctrl['cpu_time_used'])
def preemptible(self):
return self.ctrl['is_preemptible']
@@ -259,6 +285,9 @@ class control():
def registers(self):
return registers(self.ctrl['Registers'])
+ def is_idle(self):
+ return (self.id() & 0xff000000) == 0x90000000
+
def brief(self):
return "'%s' (c:%d, r:%d)" % \
(self.name(), self.current_priority(), self.real_priority())
@@ -266,10 +295,13 @@ class control():
class queue():
"""Manage the Thread_queue_Control."""
- priority_headers = 4
-
def __init__(self, que):
- self.que = que
+ if que.type.code == gdb.TYPE_CODE_PTR:
+ self.reference = que
+ self.que = que.dereference()
+ else:
+ self.que = que
+ self.reference = que.address
def fifo(self):
return str(self.que['discipline']) == 'THREAD_QUEUE_DISCIPLINE_FIFO'
@@ -284,8 +316,5 @@ class queue():
if self.fifo():
t = task_chain(chains.control(self.que['Queues']['Fifo']))
else:
- t = []
- for ph in range(0, self.priority_headers):
- t.extend(task_chain(chains.control( \
- self.que['Queues']['Priority'][ph])))
+ t = task_tree(rbtrees.control(self.que['Queues']['Priority']))
return t
diff --git a/tools/gdb/python/time.py b/tools/gdb/python/time.py
new file mode 100644
index 0000000..16cf83f
--- /dev/null
+++ b/tools/gdb/python/time.py
@@ -0,0 +1,79 @@
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010-2015 Chris Johns (chrisj@rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# RTEMS Time Support
+#
+
+import gdb
+
+class time():
+
+ def __init__(self, time_, ticks = False, scaler = 1000000000):
+ self.ticks = ticks
+ self.scaler = scaler
+ if time_.type.code == gdb.TYPE_CODE_PTR:
+ self.reference = time_
+ self.time = time_.dereference()
+ else:
+ self.time = time_
+ self.reference = time_.address
+ if self.time.type.strip_typedefs().tag == 'timespec':
+ self.timespecs = True
+ else:
+ self.timespecs = False
+
+ def __str__(self):
+ return self.tostring()
+
+ def get(self):
+ if self.timespecs:
+ return (long(self.time['tv_sec']) * 1000000000) + long(self.time['tv_nsec'])
+ else:
+ return long(self.time) * self.scaler
+
+ def tostring(self):
+ if self.ticks:
+ return '%d ticks' % (self.time)
+ nsecs = self.get()
+ secs = nsecs / 1000000000
+ nsecs = nsecs % 1000000000
+ minutes = secs / 60
+ secs = secs % 60
+ hours = minutes / 60
+ minutes = minutes % 60
+ days = hours / 24
+ hours = hours % 24
+ t = ''
+ if days:
+ t = '%dd ' % (days)
+ if hours or minutes or secs:
+ t += '%02d:%02d:%02d ' % (hours, minutes, secs)
+ t += '%d nsec' % (nsecs)
+ return t