source: rtems-tools/tools/gdb/python/classic.py @ 3162858

4.104.11
Last change on this file since 3162858 was 3162858, checked in by Chris Johns <chrisj@…>, on Aug 26, 2014 at 4:57:57 AM

gdb-python: Update so 'rtems task' lists the classic tasks.

This is a first pass at cleaning up the support. To use:

$ waf configure --prefix=$HOME/development/rtems/4.11
$ waf build install

Start GDB and break at Init:

(gdb) py import rtems
(gdb) rtems task

will list the classic API tasks.

  • Property mode set to 100644
File size: 10.6 KB
Line 
1# RTEMS Tools Project (http://www.rtems.org/)
2# Copyright 2010-2014 Chris Johns (chrisj@rtems.org)
3# All rights reserved.
4#
5# This file is part of the RTEMS Tools package in 'rtems-tools'.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions are met:
9#
10# 1. Redistributions of source code must retain the above copyright notice,
11# this list of conditions and the following disclaimer.
12#
13# 2. Redistributions in binary form must reproduce the above copyright notice,
14# this list of conditions and the following disclaimer in the documentation
15# and/or other materials provided with the distribution.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27# POSSIBILITY OF SUCH DAMAGE.
28#
29
30#
31# RTEMS Classic API Support
32#
33
34import gdb
35import itertools
36import re
37#ToDo This shouldn't be here
38import helper
39
40import objects
41import threads
42import watchdog
43import heaps
44import supercore
45
46class attribute:
47    """The Classic API attribute."""
48
49    groups = {
50        'none' : [],
51        'all' : ['scope',
52                 'priority',
53                 'fpu',
54                 'semaphore-type',
55                 'semaphore-pri',
56                 'semaphore-pri-ceiling',
57                 'barrier',
58                 'task'],
59        'task' : ['scope',
60                  'priority',
61                  'fpu',
62                  'task'],
63        'semaphore' : ['scope',
64                       'priority',
65                       'semaphore-type',
66                       'semaphore-pri',
67                       'semaphore-pri-ceiling'],
68        'barrier' : ['barrier'],
69        'message_queue' : ['priority',
70                           'scope'],
71        'partition' : ['scope'],
72        'region' : ['priority']
73        }
74
75    masks = {
76        'scope' : 0x00000002,
77        'priority' : 0x00000004,
78        'fpu' : 0x00000001,
79        'semaphore-type' : 0x00000030,
80        'semaphore-pri' : 0x00000040,
81        'semaphore-pri-ceiling' : 0x00000080,
82        'barrier' : 0x00000010,
83        'task' : 0x00008000
84        }
85
86    fields = {
87        'scope' : [(0x00000000, 'local'),
88                   (0x00000002, 'global')],
89        'priority' : [(0x00000000, 'fifo'),
90                      (0x00000004, 'pri')],
91        'fpu' : [(0x00000000, 'no-fpu'),
92                 (0x00000001, 'fpu')],
93        'semaphore-type' : [(0x00000000, 'count-sema'),
94                            (0x00000010, 'bin-sema'),
95                            (0x00000020, 'simple-bin-sema')],
96        'semaphore-pri' : [(0x00000000, 'no-inherit-pri'),
97                           (0x00000040, 'inherit-pri')],
98        'semaphore-pri-ceiling' : [(0x00000000, 'no-pri-ceiling'),
99                                   (0x00000080, 'pri-ceiling')],
100        'barrier' : [(0x00000010, 'barrier-auto-release'),
101                     (0x00000000, 'barrier-manual-release')],
102        'task' : [(0x00000000, 'app-task'),
103                  (0x00008000, 'sys-task')]
104        }
105
106    def __init__(self, attr, attrtype = 'none'):
107        if attrtype not in self.groups:
108            raise 'invalid attribute type'
109        self.attrtype = attrtype
110        self.attr = attr
111
112    #ToDo: Move this out
113    def to_string(self):
114        s = '0x%08x,' % (self.attr)
115        if self.attrtype != 'none':
116            for m in self.groups[self.attrtype]:
117                v = self.attr & self.masks[m]
118                for f in self.fields[m]:
119                    if f[0] == v:
120                        s += f[1] + ','
121                        break
122        return s[:-1]
123
124    def test(self, mask, value):
125        if self.attrtype != 'none' and \
126                mask in self.groups[self.attrtype]:
127            v = self.masks[mask] & self.attr
128            for f in self.fields[mask]:
129                if v == f[0] and value == f[1]:
130                    return True
131        return False
132
133
134class semaphore:
135    "Print a classic semaphore."
136
137    def __init__(self, obj):
138        self.reference = obj
139        self.object = obj.dereference()
140        self.object_control = objects.control(self.object['Object'])
141        self.attr = attribute(self.object['attribute_set'], 'semaphore')
142
143    def show(self, from_tty):
144        print '     Name:', self.object_control.name()
145        print '     Attr:', self.attr.to_string()
146        if self.attr.test('semaphore-type', 'bin-sema') or \
147                self.attr.test('semaphore-type', 'simple-bin-sema'):
148            core_mutex = self.object['Core_control']['mutex']
149            locked = core_mutex['lock'] == 0
150            if locked:
151                s = 'locked'
152            else:
153                s = 'unlocked'
154            print '     Lock:', s
155            print '  Nesting:', core_mutex['nest_count']
156            print '  Blocked:', core_mutex['blocked_count']
157            print '   Holder:',
158            holder = core_mutex['holder']
159            if holder and locked:
160                holder = threads.control(holder.dereference())
161                print holder.brief()
162            elif holder == 0 and locked:
163                print 'locked but no holder'
164            else:
165                print 'unlocked'
166            wait_queue = threads.queue(core_mutex['Wait_queue'])
167            tasks = wait_queue.tasks()
168            print '    Queue: len = %d, state = %s' % (len(tasks),
169                                                       wait_queue.state())
170            print '    Tasks:'
171            print '    Name (c:current, r:real), (id)'
172            for t in range(0, len(tasks)):
173                print '      ', tasks[t].brief(), ' (%08x)' % (tasks[t].id())
174        else:
175            print 'semaphore'
176
177class task:
178    "Print a classic task"
179
180    def __init__(self, obj):
181        self.reference = obj
182        self.object = obj.dereference()
183        self.task = threads.control(self.reference)
184        self.wait_info = self.task.wait_info()
185        self.regs = self.task.registers()
186        #self.regs = sparc.register(self.object['Registers'])
187
188    def show(self, from_tty):
189        cpu = self.task.executing()
190        if cpu == -1:
191            cpu = 'not executing'
192        print '         Id:', '0x%08x' % (self.task.id())
193        print '       Name:', self.task.name()
194        print ' Active CPU:', cpu
195        print '      State:', self.task.current_state()
196        print '    Current:', self.task.current_priority()
197        print '       Real:', self.task.real_priority()
198        print '    Preempt:', self.task.preemptible()
199        print '   T Budget:', self.task.cpu_time_budget()
200        print '       Time:', self.task.cpu_time_used()
201        print '  Resources:', self.task.resource_count()
202        print '  Regsters:'
203        for name in self.regs.names():
204            val = self.regs.get(name)
205            print '    %20s: %08x (%d)' % (name, val, val)
206
207class message_queue:
208    "Print classic messege queue"
209
210    def __init__(self, obj):
211        self.reference = obj
212        self.object = obj.dereference()
213        self.object_control = objects.control(self.object['Object'])
214        self.attr = attribute(self.object['attribute_set'], \
215            'message_queue')
216        self.wait_queue = threads.queue( \
217            self.object['message_queue']['Wait_queue'])
218
219        self.core_control = supercore.message_queue(self.object['message_queue'])
220
221    def show(self, from_tty):
222        print '     Name:', self.object_control.name()
223        print '     Attr:', self.attr.to_string()
224
225        self.core_control.show()
226
227class timer:
228    '''Print a classic timer'''
229
230    def __init__(self, obj):
231        self.reference = obj
232        self.object = obj.dereference()
233        self.object_control = objects.control(self.object['Object'])
234        self.watchdog = watchdog.control(self.object['Ticker'])
235
236    def show(self, from_tty):
237        print '     Name:', self.object_control.name()
238        self.watchdog.show()
239
240class partition:
241    ''' Print a rtems partition '''
242
243    def __init__(self, obj):
244        self.reference = obj
245        self.object = obj.dereference()
246        self.object_control = objects.control(self.object['Object'])
247        self.attr = attribute(self.object['attribute_set'], 'partition')
248        self.starting_addr = self.object['starting_address']
249        self.length = self.object['length']
250        self.buffer_size = self.object['buffer_size']
251        self.used_blocks = self.object['number_of_used_blocks']
252
253    def show(self, from_tty):
254        # ToDo: the printing still somewhat crude.
255        print '     Name:', self.object_control.name()
256        print '     Attr:', self.attr.to_string()
257        print '   Length:', self.length
258        print '   B Size:', self.buffer_size
259        print ' U Blocks:', self.used_blocks
260
261class region:
262    "prints a classic region"
263
264    def __init__(self, obj):
265        self.reference = obj
266        self.object = obj.dereference()
267        self.object_control = objects.control(self.object['Object'])
268        self.attr = attribute(self.object['attribute_set'], 'region')
269        self.wait_queue = threads.queue(self.object['Wait_queue'])
270        self.heap = heaps.control(self.object['Memory'])
271
272    def show(self, from_tty):
273        print '     Name:', self.object_control.name()
274        print '     Attr:', self.attr.to_string()
275        helper.tasks_printer_routine(self.wait_queue)
276        print '   Memory:'
277        self.heap.show()
278
279class barrier:
280    '''classic barrier abstraction'''
281
282    def __init__(self, obj):
283        self.reference = obj
284        self.object = obj.dereference()
285        self.object_control = objects.control(self.object['Object'])
286        self.attr = attribute(self.object['attribute_set'],'barrier')
287        self.core_b_control = supercore.barrier_control(self.object['Barrier'])
288
289    def show(self,from_tty):
290        print '     Name:',self.object_control.name()
291        print '     Attr:',self.attr.to_string()
292
293        if self.attr.test('barrier','barrier-auto-release'):
294            max_count = self.core_b_control.max_count()
295            print 'Aut Count:', max_count
296
297        print '  Waiting:',self.core_b_control.waiting_threads()
298        helper.tasks_printer_routine(self.core_b_control.tasks())
Note: See TracBrowser for help on using the repository browser.