emdbg.analyze.backtrace

  1# Copyright (c) 2023, Auterion AG
  2# SPDX-License-Identifier: BSD-3-Clause
  3
  4from __future__ import annotations
  5import re
  6from pathlib import Path
  7from .priority import _BoostOperation
  8
  9class Frame:
 10    """
 11    Parses a GDB frame of a `backtrace` or `px4_backtrace` command.
 12    """
 13    def __init__(self, description: str):
 14        """
 15        :param description: A single line of the backtrace command starting with a `#`
 16        """
 17        self.is_valid = False
 18        self.description = description
 19        if match := re.match(r"#(\d+) +(?:0x.+? in )?(.+)\((.*?)\) at (.+?):(\d+)", description):
 20            self.index = int(match.group(1))
 21            self.function_name = match.group(2)
 22            self.args = match.group(3)
 23            self.filename = match.group(4)
 24            self.line = match.group(5)
 25            self.is_valid = True
 26            self.function = f"{self.function_name}({self.args})"
 27            self.location = f"{Path(self.filename).relative_to(Path().cwd())}:{self.line}"
 28            self._unique_location = self.function + "\n" + self.location
 29
 30    def __hash__(self) -> int:
 31        return hash(self._node)
 32
 33    def __eq__(self, other) -> int:
 34        return self.function == other.function and self.filename == other.filename
 35
 36    def __repr__(self) -> str:
 37        return self.function
 38
 39    def __str__(self) -> str:
 40        return f"#{self.index:<2} {self.function}"
 41
 42
 43class Backtrace:
 44    """
 45    Holds the entire call chain of a `backtrace` or `px4_backtrace` command.
 46    """
 47    EDGES = {}
 48    COLORS = {}
 49
 50    def __init__(self, description: str):
 51        """
 52        :param description: All lines of the backtrace command
 53        """
 54        self.description = description
 55        tasks = (re.match(r"Task=(.+)", d) for d in description.splitlines())
 56        tasks = [t.group(1) for t in tasks if t is not None]
 57        self.task = tasks[0] if tasks else None
 58        self.type = self.task
 59
 60        frames = (Frame(d) for d in description.splitlines())
 61        self.frames = [f for f in frames if f.is_valid]
 62        self.is_valid = len(self.frames)
 63        if self.is_valid:
 64            funcs = {f.function for f in self.frames}
 65            for name, pattern in self.EDGES.items():
 66                if any(re.search(pattern, f) for f in funcs):
 67                    self.type = name
 68                    break
 69
 70    def __hash__(self) -> int:
 71        return hash("".join(f.filename + f.function for f in self.frames))
 72
 73    def __eq__(self, other) -> int:
 74        ours = "".join(f.filename + f.function for f in self.frames)
 75        others = "".join(f.filename + f.function for f in other.frames)
 76        return ours == others
 77
 78    def __repr__(self) -> str:
 79        return str(self.frames)
 80
 81# -----------------------------------------------------------------------------
 82def _fill(color):
 83    return {"style": "filled", "fillcolor": color}
 84
 85def _bfill(color):
 86    return {"style": "bold,filled", "fillcolor": color}
 87
 88
 89class FileSystemBacktrace(Backtrace):
 90    EDGES = dict(
 91        READ = r"^read$",
 92        WRITE = r"^write$",
 93        FSYNC = r"^fsync$",
 94        UNLINK = r"^unlink$",
 95        LSEEK = r"^lseek$",
 96        OPEN = r"^open$",
 97        CLOSE = r"^close$",
 98        READDIR = r"^readdir$",
 99        OPENDIR = r"^opendir$",
100        MOUNT = r"^mount$",
101        MKDIR = r"^mkdir$",
102        STAT = r"^stat$",
103        IRQ = r"^stm32_sdmmc_interrupt$",
104        INIT = r"^stm32_sdio_initialize$",
105    )
106    COLORS = {**{"^fat_.*$": _fill("LightYellow"),
107                 "^mmc?sd_.*$": _fill("LightCyan"),
108                 "^stm32_.*$": _fill("DarkSeaGreen"),
109                 "px4::logger::": _fill("Gold"),
110                 "Navigator": _fill("GreenYellow"),
111                 "can": _fill("LightSalmon"),
112                 "^nsh_.*": _fill("LightSkyBlue"),
113                 "^(param|bson)_.*": _fill("Bisque")},
114              **{pattern: _bfill("Silver") for pattern in EDGES.values()}}
115
116
117class SpiBacktrace(Backtrace):
118    EDGES = dict(
119        READ = r"RegisterRead|FIFOReadCount",
120        WRITE = r"RegisterWrite",
121        PARAM = r"^param_main$",
122        NSH = r"^nsh_initialize$",
123    )
124    COLORS = {**{pattern: _bfill("Silver") for pattern in EDGES.values()},
125              **{"^(ramtron|bch|bchlib)_.*$": _fill("LightYellow"),
126                 "^spi_.*$": _fill("LightCyan"),
127                 "^stm32_.*$": _fill("DarkSeaGreen"),
128                 "ICM20602": _fill("Gold"),
129                 "BMI088": _fill("GreenYellow"),
130                 "ICM42688": _fill("LightSalmon"),
131                 "^nsh_.*": _fill("LightSkyBlue"),
132                 "^(param|bson)_.*": _fill("Bisque")}}
133
134
135class I2cBacktrace(Backtrace):
136    EDGES = dict(
137        TRANSFER = r"stm32_i2c_transfer",
138        NSH = r"^nsh_initialize$",
139        IRQ = r"^stm32_i2c_isr$",
140        INIT = r"^stm32_i2c_setclock$",
141    )
142    COLORS = {**{"^stm32_.*$": _fill("DarkSeaGreen"),
143                 "BMM150": _fill("Yellow"),
144                 "IST8310": _fill("Cyan"),
145                 "BMP388": _fill("Gold"),
146                 "RGBLED": _fill("LightSkyBlue"),
147                 "MCP23009": _fill("LightSalmon")},
148              **{pattern: _bfill("Silver") for pattern in EDGES.values()}}
149
150
151class CanBacktrace(Backtrace):
152    EDGES = dict(
153        SEND = r"CanIface::send$",
154        RECEIVE = r"CanIface::receive$",
155        INIT = r"CanIface::init$",
156        FRAME = r"TransferListener::handleFrame$",
157    )
158    COLORS = {**{pattern: _bfill("Silver") for pattern in EDGES.values()},
159              **{"^(ramtron|bch|bchlib)_.*$": _fill("LightYellow"),
160                 "Publisher": _fill("DarkSeaGreen")}}
161
162
163class UartBacktrace(Backtrace):
164    EDGES = dict(
165        READ = r"^read$",
166        WRITE = r"^write$",
167        FFLUSH = r"^fflush$",
168        FPUTC = r"^fputc$",
169        FPUTS = r"^fputs$",
170        OPEN = r"^open$",
171        SYSLOG = r"^syslog$",
172        PRINTF = r"^printf$",
173        IRQ = r"^irq_dispatch$",
174        INIT = r"^arm_earlyserialinit$",
175    )
176    COLORS = {**{"^I2CSPI": _fill("LightYellow"),
177                 "^(up|uart)_.*$": _fill("LightCyan"),
178                 "^stm32_.*$": _fill("DarkSeaGreen"),
179                 "px4::logger": _fill("Gold"),
180                 "[mM]avlink": _fill("GreenYellow"),
181                 "can": _fill("LightSalmon"),
182                 "^nsh_.*": _fill("LightSkyBlue"),
183                 "^(param|bson)_.*": _fill("Bisque")},
184              **{pattern: _bfill("Silver") for pattern in EDGES.values()}}
185
186
187class SemaphoreBacktrace(Backtrace):
188    # EDGES = dict(
189    #     RESTORE = r"^nxsem_restoreholderprio$",
190    #     BOOST =  r"^nxsem_boostholderprio$",
191    #     WAIT = r"^nxsem_wait$",
192    #     POST = r"^nxsem_post$",
193    #     INIT = r"^sem_init$",
194    #     DESTROY = r"^sem_destroy$",
195    #     FREE = r"^free$",
196    #     MALLOC = r"^malloc$",
197    #     MEMSET = r"^memset$",
198    # )
199    # COLORS = {pattern: _bfill("Silver") for pattern in EDGES.values()}
200    def __init__(self, description: str):
201        """
202        :param description: All lines of the backtrace command also containing a boost trace command.
203        """
204        super().__init__(description)
205        ops = (_BoostOperation(d) for d in description.splitlines())
206        ops = [o for o in ops if o.is_valid]
207        self.operation = ops[0] if ops else None
208        if self.operation is not None:
209            self.type = self.operation.task
210        if ops and self.operation.prio_to == 255:
211            if self.type is not None:
212                self.type += "_255"
213            else:
214                self.type = "255"
class Frame:
10class Frame:
11    """
12    Parses a GDB frame of a `backtrace` or `px4_backtrace` command.
13    """
14    def __init__(self, description: str):
15        """
16        :param description: A single line of the backtrace command starting with a `#`
17        """
18        self.is_valid = False
19        self.description = description
20        if match := re.match(r"#(\d+) +(?:0x.+? in )?(.+)\((.*?)\) at (.+?):(\d+)", description):
21            self.index = int(match.group(1))
22            self.function_name = match.group(2)
23            self.args = match.group(3)
24            self.filename = match.group(4)
25            self.line = match.group(5)
26            self.is_valid = True
27            self.function = f"{self.function_name}({self.args})"
28            self.location = f"{Path(self.filename).relative_to(Path().cwd())}:{self.line}"
29            self._unique_location = self.function + "\n" + self.location
30
31    def __hash__(self) -> int:
32        return hash(self._node)
33
34    def __eq__(self, other) -> int:
35        return self.function == other.function and self.filename == other.filename
36
37    def __repr__(self) -> str:
38        return self.function
39
40    def __str__(self) -> str:
41        return f"#{self.index:<2} {self.function}"

Parses a GDB frame of a backtrace or px4_backtrace command.

Frame(description: str)
14    def __init__(self, description: str):
15        """
16        :param description: A single line of the backtrace command starting with a `#`
17        """
18        self.is_valid = False
19        self.description = description
20        if match := re.match(r"#(\d+) +(?:0x.+? in )?(.+)\((.*?)\) at (.+?):(\d+)", description):
21            self.index = int(match.group(1))
22            self.function_name = match.group(2)
23            self.args = match.group(3)
24            self.filename = match.group(4)
25            self.line = match.group(5)
26            self.is_valid = True
27            self.function = f"{self.function_name}({self.args})"
28            self.location = f"{Path(self.filename).relative_to(Path().cwd())}:{self.line}"
29            self._unique_location = self.function + "\n" + self.location
Parameters
  • description: A single line of the backtrace command starting with a #
is_valid
description
class Backtrace:
44class Backtrace:
45    """
46    Holds the entire call chain of a `backtrace` or `px4_backtrace` command.
47    """
48    EDGES = {}
49    COLORS = {}
50
51    def __init__(self, description: str):
52        """
53        :param description: All lines of the backtrace command
54        """
55        self.description = description
56        tasks = (re.match(r"Task=(.+)", d) for d in description.splitlines())
57        tasks = [t.group(1) for t in tasks if t is not None]
58        self.task = tasks[0] if tasks else None
59        self.type = self.task
60
61        frames = (Frame(d) for d in description.splitlines())
62        self.frames = [f for f in frames if f.is_valid]
63        self.is_valid = len(self.frames)
64        if self.is_valid:
65            funcs = {f.function for f in self.frames}
66            for name, pattern in self.EDGES.items():
67                if any(re.search(pattern, f) for f in funcs):
68                    self.type = name
69                    break
70
71    def __hash__(self) -> int:
72        return hash("".join(f.filename + f.function for f in self.frames))
73
74    def __eq__(self, other) -> int:
75        ours = "".join(f.filename + f.function for f in self.frames)
76        others = "".join(f.filename + f.function for f in other.frames)
77        return ours == others
78
79    def __repr__(self) -> str:
80        return str(self.frames)

Holds the entire call chain of a backtrace or px4_backtrace command.

Backtrace(description: str)
51    def __init__(self, description: str):
52        """
53        :param description: All lines of the backtrace command
54        """
55        self.description = description
56        tasks = (re.match(r"Task=(.+)", d) for d in description.splitlines())
57        tasks = [t.group(1) for t in tasks if t is not None]
58        self.task = tasks[0] if tasks else None
59        self.type = self.task
60
61        frames = (Frame(d) for d in description.splitlines())
62        self.frames = [f for f in frames if f.is_valid]
63        self.is_valid = len(self.frames)
64        if self.is_valid:
65            funcs = {f.function for f in self.frames}
66            for name, pattern in self.EDGES.items():
67                if any(re.search(pattern, f) for f in funcs):
68                    self.type = name
69                    break
Parameters
  • description: All lines of the backtrace command
EDGES = {}
COLORS = {}
description
task
type
frames
is_valid
class FileSystemBacktrace(Backtrace):
 90class FileSystemBacktrace(Backtrace):
 91    EDGES = dict(
 92        READ = r"^read$",
 93        WRITE = r"^write$",
 94        FSYNC = r"^fsync$",
 95        UNLINK = r"^unlink$",
 96        LSEEK = r"^lseek$",
 97        OPEN = r"^open$",
 98        CLOSE = r"^close$",
 99        READDIR = r"^readdir$",
100        OPENDIR = r"^opendir$",
101        MOUNT = r"^mount$",
102        MKDIR = r"^mkdir$",
103        STAT = r"^stat$",
104        IRQ = r"^stm32_sdmmc_interrupt$",
105        INIT = r"^stm32_sdio_initialize$",
106    )
107    COLORS = {**{"^fat_.*$": _fill("LightYellow"),
108                 "^mmc?sd_.*$": _fill("LightCyan"),
109                 "^stm32_.*$": _fill("DarkSeaGreen"),
110                 "px4::logger::": _fill("Gold"),
111                 "Navigator": _fill("GreenYellow"),
112                 "can": _fill("LightSalmon"),
113                 "^nsh_.*": _fill("LightSkyBlue"),
114                 "^(param|bson)_.*": _fill("Bisque")},
115              **{pattern: _bfill("Silver") for pattern in EDGES.values()}}

Holds the entire call chain of a backtrace or px4_backtrace command.

EDGES = {'READ': '^read$', 'WRITE': '^write$', 'FSYNC': '^fsync$', 'UNLINK': '^unlink$', 'LSEEK': '^lseek$', 'OPEN': '^open$', 'CLOSE': '^close$', 'READDIR': '^readdir$', 'OPENDIR': '^opendir$', 'MOUNT': '^mount$', 'MKDIR': '^mkdir$', 'STAT': '^stat$', 'IRQ': '^stm32_sdmmc_interrupt$', 'INIT': '^stm32_sdio_initialize$'}
COLORS = {'^fat_.*$': {'style': 'filled', 'fillcolor': 'LightYellow'}, '^mmc?sd_.*$': {'style': 'filled', 'fillcolor': 'LightCyan'}, '^stm32_.*$': {'style': 'filled', 'fillcolor': 'DarkSeaGreen'}, 'px4::logger::': {'style': 'filled', 'fillcolor': 'Gold'}, 'Navigator': {'style': 'filled', 'fillcolor': 'GreenYellow'}, 'can': {'style': 'filled', 'fillcolor': 'LightSalmon'}, '^nsh_.*': {'style': 'filled', 'fillcolor': 'LightSkyBlue'}, '^(param|bson)_.*': {'style': 'filled', 'fillcolor': 'Bisque'}, '^read$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^write$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^fsync$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^unlink$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^lseek$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^open$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^close$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^readdir$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^opendir$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^mount$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^mkdir$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^stat$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^stm32_sdmmc_interrupt$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^stm32_sdio_initialize$': {'style': 'bold,filled', 'fillcolor': 'Silver'}}
class SpiBacktrace(Backtrace):
118class SpiBacktrace(Backtrace):
119    EDGES = dict(
120        READ = r"RegisterRead|FIFOReadCount",
121        WRITE = r"RegisterWrite",
122        PARAM = r"^param_main$",
123        NSH = r"^nsh_initialize$",
124    )
125    COLORS = {**{pattern: _bfill("Silver") for pattern in EDGES.values()},
126              **{"^(ramtron|bch|bchlib)_.*$": _fill("LightYellow"),
127                 "^spi_.*$": _fill("LightCyan"),
128                 "^stm32_.*$": _fill("DarkSeaGreen"),
129                 "ICM20602": _fill("Gold"),
130                 "BMI088": _fill("GreenYellow"),
131                 "ICM42688": _fill("LightSalmon"),
132                 "^nsh_.*": _fill("LightSkyBlue"),
133                 "^(param|bson)_.*": _fill("Bisque")}}

Holds the entire call chain of a backtrace or px4_backtrace command.

EDGES = {'READ': 'RegisterRead|FIFOReadCount', 'WRITE': 'RegisterWrite', 'PARAM': '^param_main$', 'NSH': '^nsh_initialize$'}
COLORS = {'RegisterRead|FIFOReadCount': {'style': 'bold,filled', 'fillcolor': 'Silver'}, 'RegisterWrite': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^param_main$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^nsh_initialize$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^(ramtron|bch|bchlib)_.*$': {'style': 'filled', 'fillcolor': 'LightYellow'}, '^spi_.*$': {'style': 'filled', 'fillcolor': 'LightCyan'}, '^stm32_.*$': {'style': 'filled', 'fillcolor': 'DarkSeaGreen'}, 'ICM20602': {'style': 'filled', 'fillcolor': 'Gold'}, 'BMI088': {'style': 'filled', 'fillcolor': 'GreenYellow'}, 'ICM42688': {'style': 'filled', 'fillcolor': 'LightSalmon'}, '^nsh_.*': {'style': 'filled', 'fillcolor': 'LightSkyBlue'}, '^(param|bson)_.*': {'style': 'filled', 'fillcolor': 'Bisque'}}
class I2cBacktrace(Backtrace):
136class I2cBacktrace(Backtrace):
137    EDGES = dict(
138        TRANSFER = r"stm32_i2c_transfer",
139        NSH = r"^nsh_initialize$",
140        IRQ = r"^stm32_i2c_isr$",
141        INIT = r"^stm32_i2c_setclock$",
142    )
143    COLORS = {**{"^stm32_.*$": _fill("DarkSeaGreen"),
144                 "BMM150": _fill("Yellow"),
145                 "IST8310": _fill("Cyan"),
146                 "BMP388": _fill("Gold"),
147                 "RGBLED": _fill("LightSkyBlue"),
148                 "MCP23009": _fill("LightSalmon")},
149              **{pattern: _bfill("Silver") for pattern in EDGES.values()}}

Holds the entire call chain of a backtrace or px4_backtrace command.

EDGES = {'TRANSFER': 'stm32_i2c_transfer', 'NSH': '^nsh_initialize$', 'IRQ': '^stm32_i2c_isr$', 'INIT': '^stm32_i2c_setclock$'}
COLORS = {'^stm32_.*$': {'style': 'filled', 'fillcolor': 'DarkSeaGreen'}, 'BMM150': {'style': 'filled', 'fillcolor': 'Yellow'}, 'IST8310': {'style': 'filled', 'fillcolor': 'Cyan'}, 'BMP388': {'style': 'filled', 'fillcolor': 'Gold'}, 'RGBLED': {'style': 'filled', 'fillcolor': 'LightSkyBlue'}, 'MCP23009': {'style': 'filled', 'fillcolor': 'LightSalmon'}, 'stm32_i2c_transfer': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^nsh_initialize$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^stm32_i2c_isr$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^stm32_i2c_setclock$': {'style': 'bold,filled', 'fillcolor': 'Silver'}}
class CanBacktrace(Backtrace):
152class CanBacktrace(Backtrace):
153    EDGES = dict(
154        SEND = r"CanIface::send$",
155        RECEIVE = r"CanIface::receive$",
156        INIT = r"CanIface::init$",
157        FRAME = r"TransferListener::handleFrame$",
158    )
159    COLORS = {**{pattern: _bfill("Silver") for pattern in EDGES.values()},
160              **{"^(ramtron|bch|bchlib)_.*$": _fill("LightYellow"),
161                 "Publisher": _fill("DarkSeaGreen")}}

Holds the entire call chain of a backtrace or px4_backtrace command.

EDGES = {'SEND': 'CanIface::send$', 'RECEIVE': 'CanIface::receive$', 'INIT': 'CanIface::init$', 'FRAME': 'TransferListener::handleFrame$'}
COLORS = {'CanIface::send$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, 'CanIface::receive$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, 'CanIface::init$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, 'TransferListener::handleFrame$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^(ramtron|bch|bchlib)_.*$': {'style': 'filled', 'fillcolor': 'LightYellow'}, 'Publisher': {'style': 'filled', 'fillcolor': 'DarkSeaGreen'}}
class UartBacktrace(Backtrace):
164class UartBacktrace(Backtrace):
165    EDGES = dict(
166        READ = r"^read$",
167        WRITE = r"^write$",
168        FFLUSH = r"^fflush$",
169        FPUTC = r"^fputc$",
170        FPUTS = r"^fputs$",
171        OPEN = r"^open$",
172        SYSLOG = r"^syslog$",
173        PRINTF = r"^printf$",
174        IRQ = r"^irq_dispatch$",
175        INIT = r"^arm_earlyserialinit$",
176    )
177    COLORS = {**{"^I2CSPI": _fill("LightYellow"),
178                 "^(up|uart)_.*$": _fill("LightCyan"),
179                 "^stm32_.*$": _fill("DarkSeaGreen"),
180                 "px4::logger": _fill("Gold"),
181                 "[mM]avlink": _fill("GreenYellow"),
182                 "can": _fill("LightSalmon"),
183                 "^nsh_.*": _fill("LightSkyBlue"),
184                 "^(param|bson)_.*": _fill("Bisque")},
185              **{pattern: _bfill("Silver") for pattern in EDGES.values()}}

Holds the entire call chain of a backtrace or px4_backtrace command.

EDGES = {'READ': '^read$', 'WRITE': '^write$', 'FFLUSH': '^fflush$', 'FPUTC': '^fputc$', 'FPUTS': '^fputs$', 'OPEN': '^open$', 'SYSLOG': '^syslog$', 'PRINTF': '^printf$', 'IRQ': '^irq_dispatch$', 'INIT': '^arm_earlyserialinit$'}
COLORS = {'^I2CSPI': {'style': 'filled', 'fillcolor': 'LightYellow'}, '^(up|uart)_.*$': {'style': 'filled', 'fillcolor': 'LightCyan'}, '^stm32_.*$': {'style': 'filled', 'fillcolor': 'DarkSeaGreen'}, 'px4::logger': {'style': 'filled', 'fillcolor': 'Gold'}, '[mM]avlink': {'style': 'filled', 'fillcolor': 'GreenYellow'}, 'can': {'style': 'filled', 'fillcolor': 'LightSalmon'}, '^nsh_.*': {'style': 'filled', 'fillcolor': 'LightSkyBlue'}, '^(param|bson)_.*': {'style': 'filled', 'fillcolor': 'Bisque'}, '^read$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^write$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^fflush$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^fputc$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^fputs$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^open$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^syslog$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^printf$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^irq_dispatch$': {'style': 'bold,filled', 'fillcolor': 'Silver'}, '^arm_earlyserialinit$': {'style': 'bold,filled', 'fillcolor': 'Silver'}}
class SemaphoreBacktrace(Backtrace):
188class SemaphoreBacktrace(Backtrace):
189    # EDGES = dict(
190    #     RESTORE = r"^nxsem_restoreholderprio$",
191    #     BOOST =  r"^nxsem_boostholderprio$",
192    #     WAIT = r"^nxsem_wait$",
193    #     POST = r"^nxsem_post$",
194    #     INIT = r"^sem_init$",
195    #     DESTROY = r"^sem_destroy$",
196    #     FREE = r"^free$",
197    #     MALLOC = r"^malloc$",
198    #     MEMSET = r"^memset$",
199    # )
200    # COLORS = {pattern: _bfill("Silver") for pattern in EDGES.values()}
201    def __init__(self, description: str):
202        """
203        :param description: All lines of the backtrace command also containing a boost trace command.
204        """
205        super().__init__(description)
206        ops = (_BoostOperation(d) for d in description.splitlines())
207        ops = [o for o in ops if o.is_valid]
208        self.operation = ops[0] if ops else None
209        if self.operation is not None:
210            self.type = self.operation.task
211        if ops and self.operation.prio_to == 255:
212            if self.type is not None:
213                self.type += "_255"
214            else:
215                self.type = "255"

Holds the entire call chain of a backtrace or px4_backtrace command.

SemaphoreBacktrace(description: str)
201    def __init__(self, description: str):
202        """
203        :param description: All lines of the backtrace command also containing a boost trace command.
204        """
205        super().__init__(description)
206        ops = (_BoostOperation(d) for d in description.splitlines())
207        ops = [o for o in ops if o.is_valid]
208        self.operation = ops[0] if ops else None
209        if self.operation is not None:
210            self.type = self.operation.task
211        if ops and self.operation.prio_to == 255:
212            if self.type is not None:
213                self.type += "_255"
214            else:
215                self.type = "255"
Parameters
  • description: All lines of the backtrace command also containing a boost trace command.
operation