summaryrefslogtreecommitdiffstats
path: root/solenv/gdb/libreoffice/vcl.py
blob: ce595747587a9da51721bf4afa66cc2e0f2141e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

import six
import gdb
from libreoffice.util import printing

class ImplSchedulerDataPrinter(object):
    '''Prints the ImplSchedulerData linked list.

       This can be used to dump the current state of the scheduler via:
          p *ImplGetSVData()->maSchedCtx.mpFirstSchedulerData

       This doesn't include currently invoked tasks AKA the stack.

       To dump the scheduler stack of invoked tasks use:
          p *ImplGetSVData()->maSchedCtx.mpSchedulerStack
    '''

    def __init__(self, typename, value):
        self.typename = typename
        self.value = value
        self.timer_type_ptr = gdb.lookup_type("Timer").pointer()
        self.idle_type_ptr = gdb.lookup_type("Idle").pointer()

    def as_string(self, gdbobj):
        if gdbobj['mpTask']:
            task  = gdbobj['mpTask'].dereference()
            timer = gdbobj['mpTask'].dynamic_cast( self.timer_type_ptr )
            idle  = gdbobj['mpTask'].dynamic_cast( self.idle_type_ptr )
            if idle:
                task_type = "Idle"
            elif timer:
                task_type = "Timer"
            else:
                task_type = "Task"
            res = "{:7s}{:10s} active: {:6s}".format( task_type, str(task['mePriority']).replace('TaskPriority::',''), str(task['mbActive']) )
            name = task['mpDebugName']
            if not name:
                res = res + "   (task debug name not set)"
            else:
                res = "{} '{}' ({})".format(res, str(name.string()), str(task.dynamic_type))
            val_type = gdb.lookup_type(str( task.dynamic_type )).pointer()
            timer = gdbobj['mpTask'].cast( val_type )
            if task_type == "Timer":
                res = "{}: {}ms".format(res, timer['mnTimeout'])
            elif task_type == "Idle":
                assert 0 == timer['mnTimeout'], "Idle with timeout == {}".format( timer['mnTimeout'] )
            return res
        else:
            return "(no task)"

    def to_string(self):
        return self.typename

    def children(self):
        return self._iterator(self)

    def display_hint(self):
        return 'array'

    class _iterator(six.Iterator):

        def __init__(self, printer):
            self.pos = 0
            self.printer = printer
            self.value = printer.value

        def __iter__(self):
            return self

        def __next__(self):
            if not self.value:
                raise StopIteration()

            pos = str(self.pos)
            name = "\n  " + self.printer.as_string(self.value)
            self.value = self.value['mpNext']
            self.pos += 1

            return (pos, name)

class ImplSchedulerContextPrinter(object):

    def __init__(self, typename, value):
        self.typename = typename
        self.value = value
        self.prio = gdb.lookup_type('TaskPriority')

    def to_string(self):
        res = "{\n"
        if self.value['mnTimerPeriod']:
            res = res + "mnTimerPeriod = " + str(self.value['mnTimerPeriod']) + "\n"
        if self.value['mpSchedulerStack']:
            res = res + "STACK, " + str(self.value['mpSchedulerStack'].dereference())
        if self.value['mpFirstSchedulerData']:
            for key, value in self.prio.items():
                first = self.value['mpFirstSchedulerData'][value.enumval]
                if first:
                    res = res + key.replace('TaskPriority::', '') + ", " + str(first.dereference())
        return res + "}"

printer = None

def build_pretty_printers():
    global printer

    printer = printing.Printer("libreoffice/vcl")
    printer.add('ImplSchedulerData', ImplSchedulerDataPrinter)
    printer.add('ImplSchedulerContext', ImplSchedulerContextPrinter)

def register_pretty_printers(obj):
    printing.register_pretty_printer(printer, obj)

build_pretty_printers()

# vim:set shiftwidth=4 softtabstop=4 expandtab: