summaryrefslogtreecommitdiff
path: root/solenv/gdb/libreoffice/vcl.py
blob: 07f95a6976891f5dfd2d1e0acc3971b3ec1c1bec (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
# -*- 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()->mpFirstSchedulerData

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

       To dump the scheduler stack of invoked tasks use:
          p *ImplGetSVData()->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']), 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'])
            else:
                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['mpNext']:
                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)

printer = None

def build_pretty_printers():
    global printer

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

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

build_pretty_printers()

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