source: rtems-tools/tools/gdb/python/threads.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: 9.2 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 Threads Support
32#
33
34import gdb
35
36import chains
37import objects
38import percpu
39
40def task_chain(chain):
41    tasks = []
42    node = chain.first()
43    while not node.null():
44        tasks.append(control(node.cast('Thread_Control')))
45        node.next()
46    return tasks
47
48class state():
49
50    ALL_SET = 0x000fffff
51    READY = 0x00000000
52    DORMANT = 0x00000001
53    SUSPENDED = 0x00000002
54    TRANSIENT = 0x00000004
55    DELAYING = 0x00000008
56    WAITING_FOR_TIME = 0x00000010
57    WAITING_FOR_BUFFER = 0x00000020
58    WAITING_FOR_SEGMENT = 0x00000040
59    WAITING_FOR_MESSAGE = 0x00000080
60    WAITING_FOR_EVENT = 0x00000100
61    WAITING_FOR_SEMAPHORE = 0x00000200
62    WAITING_FOR_MUTEX = 0x00000400
63    WAITING_FOR_CONDITION_VARIABLE = 0x00000800
64    WAITING_FOR_JOIN_AT_EXIT = 0x00001000
65    WAITING_FOR_RPC_REPLY = 0x00002000
66    WAITING_FOR_PERIOD = 0x00004000
67    WAITING_FOR_SIGNAL = 0x00008000
68    WAITING_FOR_BARRIER = 0x00010000
69    WAITING_FOR_RWLOCK = 0x00020000
70    INTERRUPTIBLE_BY_SIGNAL = 0x10000000
71    LOCALLY_BLOCKED = \
72        WAITING_FOR_BUFFER             | \
73        WAITING_FOR_SEGMENT            | \
74        WAITING_FOR_MESSAGE            | \
75        WAITING_FOR_SEMAPHORE          | \
76        WAITING_FOR_MUTEX              | \
77        WAITING_FOR_CONDITION_VARIABLE | \
78        WAITING_FOR_JOIN_AT_EXIT       | \
79        WAITING_FOR_SIGNAL             | \
80        WAITING_FOR_BARRIER            | \
81        WAITING_FOR_RWLOCK
82    WAITING_ON_THREAD_QUEUE = \
83        LOCALLY_BLOCKED | WAITING_FOR_RPC_REPLY
84    BLOCKED = \
85        DELAYING                | \
86        WAITING_FOR_TIME        | \
87        WAITING_FOR_PERIOD      | \
88        WAITING_FOR_EVENT       | \
89        WAITING_ON_THREAD_QUEUE | \
90        INTERRUPTIBLE_BY_SIGNAL
91
92    masks = {
93        ALL_SET : 'all-set',
94        READY : 'ready',
95        DORMANT : 'dormant',
96        SUSPENDED : 'suspended',
97        TRANSIENT : 'transient',
98        DELAYING : 'delaying',
99        WAITING_FOR_TIME : 'waiting-for-time',
100        WAITING_FOR_BUFFER : 'waiting-for-buffer',
101        WAITING_FOR_SEGMENT : 'waiting-for-segment',
102        WAITING_FOR_MESSAGE : 'waiting-for-message',
103        WAITING_FOR_EVENT : 'waiting-for-event',
104        WAITING_FOR_SEMAPHORE : 'waiting-for-semaphore',
105        WAITING_FOR_MUTEX : 'waiting-for-mutex',
106        WAITING_FOR_CONDITION_VARIABLE : 'waiting-for-condition-variable',
107        WAITING_FOR_JOIN_AT_EXIT : 'waiting-for-join-at-exit',
108        WAITING_FOR_RPC_REPLY : 'waiting-for-rpc-reply',
109        WAITING_FOR_PERIOD : 'waiting-for-period',
110        WAITING_FOR_SIGNAL : 'waiting-for-signal',
111        WAITING_FOR_BARRIER : 'waiting-for-barrier',
112        WAITING_FOR_RWLOCK : 'waiting-for-rwlock'
113        }
114
115    def __init__(self, s):
116        self.s = s
117
118    def to_string(self):
119        if (self.s & self.LOCALLY_BLOCKED) == self.LOCALLY_BLOCKED:
120            return 'locally-blocked'
121        if (self.s & self.WAITING_ON_THREAD_QUEUE) == self.WAITING_ON_THREAD_QUEUE:
122            return 'waiting-on-thread-queue'
123        if (self.s & self.BLOCKED) == self.BLOCKED:
124            return 'blocked'
125        s = ','
126        for m in self.masks:
127            if (self.s & m) == m:
128                s = self.masks[m] + ','
129        return s[:-1]
130
131class wait_info():
132
133    def __init__(self, info):
134        self.info = info
135
136    def id(self):
137        return self.info['id']
138
139    def count(self):
140        return self.info['count']
141
142    def return_arg(self):
143        return self.info['return_argument']
144
145    def option(self):
146        return self.info['option']
147
148    def block2n(self):
149        return task_chain(chains.control(self.info['Block2n']))
150
151    def queue(self):
152        return task_chain(chains.control(self.info['queue']))
153
154class registers():
155
156    def __init__(self, regs):
157        self.regs = regs
158
159    def names(self):
160        return [field.name for field in self.regs.type.fields()]
161
162    def get(self, reg):
163        t = str(self.regs[reg].type)
164        if t in ['double']:
165            return float(self.regs[reg])
166        return int(self.regs[reg])
167
168
169    def format(self, reg):
170        t = self.regs[reg].type
171        if t in ['uint32_t', 'unsigned', 'unsigned long']:
172            return '%08x (%d)' % (val)
173
174class control():
175    '''
176    Thread_Control has the following fields:
177      Object              Objects_Control
178      RBNode              RBTree_Node
179      current_state       States_Control
180      current_priority    Priority_Control
181      real_priority       Priority_Control
182      resource_count      uint32_t
183      Wait                Thread_Wait_information
184      Timer               Watchdog_Control
185      receive_packet      MP_packet_Prefix*                   X
186      lock_mutex          Chain_Control                       X
187      Resource_node       Resource_Node                       X
188      is_global           bool                                X
189      is_preemptible      bool
190      Scheduler           Thread_Scheduler_control
191      rtems_ada_self      void*                               X
192      cpu_time_budget     uint32_t
193      budget_algorithm    Thread_CPU_budget_algorithms
194      budget_callout      Thread_CPU_budget_algorithm_callout
195      cpu_time_used       Thread_CPU_usage_t
196      Start               Thread_Start_information
197      Post_switch_actions Thread_Action_control
198      Registers           Context_Control
199      fp_context          Context_Control_fp*                 X
200      libc_reent          struct _reent*
201      API_Extensions      void*[THREAD_API_LAST + 1]
202      task_variables      rtems_task_variable_t*              X
203      Key_Chain           Chain_Control
204      Life                Thread_Life_control
205      extensions          void*[RTEMS_ZERO_LENGTH_ARRAY]
206
207    where 'X' means the field is condition and may no exist.
208    '''
209
210    def __init__(self, ctrl):
211        self.reference = ctrl
212        self.ctrl = ctrl.dereference()
213        self.object = objects.control(ctrl['Object'])
214        self._executing = percpu.thread_active(self.reference)
215        self._heir = percpu.thread_heir(self.reference)
216
217    def id(self):
218        return self.object.id()
219
220    def name(self):
221        val = self.object.name()
222        if val == "":
223            val = '*'
224        return val
225
226    def executing(self):
227        return self._executing
228
229    def heir(self):
230        return self._heir
231
232    def current_state(self):
233        return state(self.ctrl['current_state']).to_string()
234
235    def current_priority(self):
236        return self.ctrl['current_priority']
237
238    def real_priority(self):
239        return self.ctrl['real_priority']
240
241    def resource_count(self):
242        return self.ctrl['resource_count']
243
244    def cpu_time_budget(self):
245        return self.ctrl['cpu_time_budget']
246
247    def cpu_time_used(self):
248        return self.ctrl['cpu_time_used']
249
250    def preemptible(self):
251        return self.ctrl['is_preemptible']
252
253    def cpu_time_budget(self):
254        return self.ctrl['cpu_time_budget']
255
256    def wait_info(self):
257        return wait_info(self.ctrl['Wait'])
258
259    def registers(self):
260        return registers(self.ctrl['Registers'])
261
262    def brief(self):
263        return "'%s' (c:%d, r:%d)" % \
264            (self.name(), self.current_priority(), self.real_priority())
265
266class queue():
267    """Manage the Thread_queue_Control."""
268
269    priority_headers = 4
270
271    def __init__(self, que):
272        self.que = que
273
274    def fifo(self):
275        return str(self.que['discipline']) == 'THREAD_QUEUE_DISCIPLINE_FIFO'
276
277    def priority(self):
278        return str(self.que['discipline']) == 'THREAD_QUEUE_DISCIPLINE_PRIORITY'
279
280    def state(self):
281        return state(self.que['state']).to_string()
282
283    def tasks(self):
284        if self.fifo():
285            t = task_chain(chains.control(self.que['Queues']['Fifo']))
286        else:
287            t = []
288            for ph in range(0, self.priority_headers):
289                t.extend(task_chain(chains.control( \
290                    self.que['Queues']['Priority'][ph])))
291        return t
Note: See TracBrowser for help on using the repository browser.