pynuttx 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. gdbrpc/__init__.py +43 -0
  2. gdbrpc/__main__.py +43 -0
  3. gdbrpc/cli.py +65 -0
  4. gdbrpc/client.py +170 -0
  5. gdbrpc/examples/getheaps.py +54 -0
  6. gdbrpc/examples/memleak.py +67 -0
  7. gdbrpc/server.py +285 -0
  8. gdbrpc/tests/stresstest.py +168 -0
  9. gdbrpc/utils.py +168 -0
  10. nxelf/__init__.py +19 -0
  11. nxelf/elf.py +635 -0
  12. nxelf/macros.py +294 -0
  13. nxgdb/__init__.py +86 -0
  14. nxgdb/autocompeletion.py +165 -0
  15. nxgdb/backtrace.py +259 -0
  16. nxgdb/circbuf.py +200 -0
  17. nxgdb/critmon.py +162 -0
  18. nxgdb/debug.py +67 -0
  19. nxgdb/diagnose.py +131 -0
  20. nxgdb/dmesg.py +90 -0
  21. nxgdb/elf.py +99 -0
  22. nxgdb/fs/__init__.py +62 -0
  23. nxgdb/fs/command.py +491 -0
  24. nxgdb/fs/fatfs.py +47 -0
  25. nxgdb/fs/fs.py +115 -0
  26. nxgdb/fs/inode.py +238 -0
  27. nxgdb/fs/littlefs.py +41 -0
  28. nxgdb/fs/lrofs.py +68 -0
  29. nxgdb/fs/romfs.py +68 -0
  30. nxgdb/fs/utils.py +42 -0
  31. nxgdb/fs/yaffs.py +98 -0
  32. nxgdb/gcore.py +144 -0
  33. nxgdb/gdbrpc.py +181 -0
  34. nxgdb/irq.py +91 -0
  35. nxgdb/kasan.py +202 -0
  36. nxgdb/libuv.py +162 -0
  37. nxgdb/lists.py +453 -0
  38. nxgdb/memcheck.py +264 -0
  39. nxgdb/memclassifier/default.py +179 -0
  40. nxgdb/memclassifier/size.py +28 -0
  41. nxgdb/memclassifier/utils.py +41 -0
  42. nxgdb/memclassify.py +410 -0
  43. nxgdb/memdump.py +1098 -0
  44. nxgdb/memleak.py +296 -0
  45. nxgdb/mm.py +896 -0
  46. nxgdb/net.py +323 -0
  47. nxgdb/noteram.py +180 -0
  48. nxgdb/notesnap.py +119 -0
  49. nxgdb/nxcrash/busyloop.py +84 -0
  50. nxgdb/nxcrash/deadlock.py +95 -0
  51. nxgdb/nxcrash/stackoverflow.py +91 -0
  52. nxgdb/nxcrash/thread.py +108 -0
  53. nxgdb/pginfo.py +130 -0
  54. nxgdb/pm.py +114 -0
  55. nxgdb/prefix.py +58 -0
  56. nxgdb/profile.py +98 -0
  57. nxgdb/protocols/circbuf.py +35 -0
  58. nxgdb/protocols/fs.py +72 -0
  59. nxgdb/protocols/irq.py +35 -0
  60. nxgdb/protocols/mm.py +122 -0
  61. nxgdb/protocols/thread.py +141 -0
  62. nxgdb/protocols/uorb.py +103 -0
  63. nxgdb/protocols/value.py +67 -0
  64. nxgdb/protocols/wdog.py +35 -0
  65. nxgdb/protocols/wqueue.py +63 -0
  66. nxgdb/quickjs.py +99 -0
  67. nxgdb/rpmsg.py +325 -0
  68. nxgdb/rpmsgtrace2pcap.py +113 -0
  69. nxgdb/stack.py +260 -0
  70. nxgdb/target.py +124 -0
  71. nxgdb/thread.py +682 -0
  72. nxgdb/tlsdump.py +153 -0
  73. nxgdb/tricore.py +166 -0
  74. nxgdb/uname.py +148 -0
  75. nxgdb/uorb.py +174 -0
  76. nxgdb/utils.py +1344 -0
  77. nxgdb/wdog.py +78 -0
  78. nxgdb/wqueue.py +194 -0
  79. nxgdbmcp/__init__.py +22 -0
  80. nxgdbmcp/__main__.py +29 -0
  81. nxgdbmcp/gmcp/__init__.py +24 -0
  82. nxgdbmcp/gmcp/context.py +25 -0
  83. nxgdbmcp/gmcp/main.py +83 -0
  84. nxgdbmcp/gmcp/session/__init__.py +26 -0
  85. nxgdbmcp/gmcp/session/context.py +75 -0
  86. nxgdbmcp/gmcp/session/gdb_session.py +66 -0
  87. nxgdbmcp/gmcp/tools/__init__.py +38 -0
  88. nxgdbmcp/gmcp/tools/command.py +41 -0
  89. nxgdbmcp/gmcp/tools/controlflow.py +216 -0
  90. nxgdbmcp/gmcp/tools/memory.py +246 -0
  91. nxgdbmcp/gmcp/tools/session.py +280 -0
  92. nxgdbmcp/gmcp/tools/shell.py +60 -0
  93. nxgdbmcp/gmcp/tools/utils.py +66 -0
  94. nxgdbmcp/gmcp/tools/value.py +113 -0
  95. nxgdbmcp/gmcp/utils.py +53 -0
  96. nxreg/__init__.py +19 -0
  97. nxreg/register.py +573 -0
  98. nxstub/__init__.py +398 -0
  99. nxstub/__main__.py +24 -0
  100. nxstub/gdbstub.py +299 -0
  101. nxstub/proxy.py +165 -0
  102. nxstub/target.py +347 -0
  103. nxstub/utils.py +136 -0
  104. nxtrace/__init__.py +19 -0
  105. nxtrace/etmv4_decoder.py +1944 -0
  106. nxtrace/general_rtt.py +346 -0
  107. nxtrace/perfetto_trace.py +456 -0
  108. nxtrace/perfetto_trace_pb2.py +2556 -0
  109. nxtrace/rtt.py +144 -0
  110. nxtrace/trace.py +907 -0
  111. pynuttx-0.0.1.dist-info/METADATA +25 -0
  112. pynuttx-0.0.1.dist-info/RECORD +114 -0
  113. pynuttx-0.0.1.dist-info/WHEEL +5 -0
  114. pynuttx-0.0.1.dist-info/top_level.txt +7 -0
gdbrpc/__init__.py ADDED
@@ -0,0 +1,43 @@
1
+ ############################################################################
2
+ # tools/pynuttx/gdbrpc/__init__.py
3
+ #
4
+ # SPDX-License-Identifier: Apache-2.0
5
+ #
6
+ # Licensed to the Apache Software Foundation (ASF) under one or more
7
+ # contributor license agreements. See the NOTICE file distributed with
8
+ # this work for additional information regarding copyright ownership. The
9
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
10
+ # "License"); you may not use this file except in compliance with the
11
+ # License. You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18
+ # License for the specific language governing permissions and limitations
19
+ # under the License.
20
+ #
21
+ ############################################################################
22
+
23
+ import importlib.util
24
+
25
+ __all__ = [
26
+ "Client",
27
+ "ClientCLI",
28
+ "PostRequest",
29
+ "Request",
30
+ "Response",
31
+ "PacketStatus",
32
+ "Server",
33
+ "ShellExec",
34
+ ]
35
+
36
+ # Client must be imported first because ClientCLI depends on it
37
+ from .client import Client
38
+ from .utils import PacketStatus, PostRequest, Request, Response, ShellExec
39
+
40
+ if importlib.util.find_spec("gdb") is not None:
41
+ from .server import Server # noqa: F401
42
+
43
+ from .cli import ClientCLI
gdbrpc/__main__.py ADDED
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/python3
2
+ ############################################################################
3
+ # tools/pynuttx/gdbrpc/__main__.py
4
+ #
5
+ # SPDX-License-Identifier: Apache-2.0
6
+ #
7
+ # Licensed to the Apache Software Foundation (ASF) under one or more
8
+ # contributor license agreements. See the NOTICE file distributed with
9
+ # this work for additional information regarding copyright ownership. The
10
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
11
+ # "License"); you may not use this file except in compliance with the
12
+ # License. You may obtain a copy of the License at
13
+ #
14
+ # http://www.apache.org/licenses/LICENSE-2.0
15
+ #
16
+ # Unless required by applicable law or agreed to in writing, software
17
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
19
+ # License for the specific language governing permissions and limitations
20
+ # under the License.
21
+ #
22
+ ############################################################################
23
+
24
+ import argparse
25
+ import os
26
+ import sys
27
+
28
+ current_dir = os.path.dirname(os.path.abspath(__file__))
29
+ parent_dir = os.path.dirname(current_dir)
30
+ if parent_dir not in sys.path:
31
+ sys.path.insert(0, parent_dir)
32
+
33
+ if __name__ == "__main__":
34
+ import gdbrpc
35
+
36
+ parser = argparse.ArgumentParser(description="GDB Socket Client")
37
+ parser.add_argument("--host", default="localhost", help="Server host")
38
+ parser.add_argument("--port", type=int, default=20819, help="Server port")
39
+
40
+ args = parser.parse_args()
41
+
42
+ client = gdbrpc.ClientCLI(args.host, args.port)
43
+ client.start()
gdbrpc/cli.py ADDED
@@ -0,0 +1,65 @@
1
+ ############################################################################
2
+ # tools/pynuttx/gdbrpc/cli.py
3
+ #
4
+ # SPDX-License-Identifier: Apache-2.0
5
+ #
6
+ # Licensed to the Apache Software Foundation (ASF) under one or more
7
+ # contributor license agreements. See the NOTICE file distributed with
8
+ # this work for additional information regarding copyright ownership. The
9
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
10
+ # "License"); you may not use this file except in compliance with the
11
+ # License. You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18
+ # License for the specific language governing permissions and limitations
19
+ # under the License.
20
+ #
21
+ ############################################################################
22
+
23
+ import logging
24
+
25
+ from gdbrpc.client import Client
26
+ from gdbrpc.utils import ShellExec
27
+
28
+
29
+ class ClientCLI(Client):
30
+ def __init__(self, host, port):
31
+ super().__init__(host, port, logLevel=logging.WARNING)
32
+
33
+ def _show_command_help(self):
34
+ print("Welcome to the GDB Remote Protocol Client")
35
+ print("Type `exit` or `quit` to disconnect.")
36
+ print("Type `help` to show this help message.")
37
+ print("If you need `interrupt` command to stop the target, use Ctrl+C.")
38
+
39
+ def _loop(self):
40
+ print("gdb> ", end="", flush=True)
41
+ while True:
42
+ try:
43
+ command = input().strip()
44
+ if not command:
45
+ continue
46
+ if command.lower() in ("exit", "quit"):
47
+ self.disconnect()
48
+ break
49
+ if command.lower() == "help":
50
+ self._show_command_help()
51
+ print("gdb> ", end="", flush=True)
52
+ continue
53
+ print(self.call(ShellExec(command)))
54
+ print("gdb> ", end="", flush=True)
55
+ except KeyboardInterrupt:
56
+ print("")
57
+ self.call(ShellExec("interrupt"))
58
+ print("gdb> ", end="", flush=True)
59
+ except EOFError:
60
+ self.disconnect()
61
+
62
+ def start(self):
63
+ assert self.connect()
64
+ self._show_command_help()
65
+ self._loop()
gdbrpc/client.py ADDED
@@ -0,0 +1,170 @@
1
+ ############################################################################
2
+ # tools/pynuttx/gdbrpc/client.py
3
+ #
4
+ # SPDX-License-Identifier: Apache-2.0
5
+ #
6
+ # Licensed to the Apache Software Foundation (ASF) under one or more
7
+ # contributor license agreements. See the NOTICE file distributed with
8
+ # this work for additional information regarding copyright ownership. The
9
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
10
+ # "License"); you may not use this file except in compliance with the
11
+ # License. You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18
+ # License for the specific language governing permissions and limitations
19
+ # under the License.
20
+ #
21
+ ############################################################################
22
+
23
+ import logging
24
+ import os
25
+ import queue
26
+ import socket
27
+ import sys
28
+ import threading
29
+ from datetime import datetime
30
+ from typing import Dict, Optional, Tuple
31
+
32
+ import cloudpickle as pickle
33
+ from gdbrpc.utils import (
34
+ DEFAULT_TIMEOUT,
35
+ PacketStatus,
36
+ PostRequest,
37
+ Request,
38
+ Response,
39
+ socket_recv,
40
+ socket_send,
41
+ )
42
+
43
+
44
+ class Client:
45
+ def __init__(self, host="localhost", port=20819, logLevel=logging.INFO):
46
+ self._host = host
47
+ self._port = port
48
+ self._socket: socket.socket
49
+ self._connected = False
50
+ self._response = queue.Queue()
51
+ self._pending_requests: Dict[int, PostRequest] = {}
52
+
53
+ self._logger = logging.getLogger(__name__)
54
+ if not self._logger.hasHandlers():
55
+ self._logger.setLevel(logLevel)
56
+ timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
57
+ pid = os.getpid()
58
+ handler = logging.FileHandler(f"gdbrpc_client-{timestamp}-pid{pid}.log")
59
+ formatter = logging.Formatter("%(asctime)s gdbrpc_client: %(message)s")
60
+ handler.setFormatter(formatter)
61
+ self._logger.addHandler(handler)
62
+
63
+ def connect(self):
64
+ try:
65
+ self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
66
+ self._socket.connect((self._host, self._port))
67
+ self._connected = True
68
+ logging.info(f"Connected to GDB server at {self._host}:{self._port}")
69
+
70
+ threading.Thread(
71
+ target=self._listen_responses, daemon=True, args=(self._socket,)
72
+ ).start()
73
+
74
+ return True
75
+ except Exception as e:
76
+ logging.error(f"Failed to connect {self._host}:{self._port}: {e}")
77
+ return False
78
+
79
+ def _listen_responses(self, socket: socket.socket):
80
+ try:
81
+ while self._connected:
82
+ data: Tuple[Response, PacketStatus] = pickle.loads(
83
+ socket_recv(socket, self._logger)
84
+ )
85
+ response, status = data
86
+ self._logger.debug(
87
+ f"Received response for request ID {response.tag}, current queue: {self._pending_requests}"
88
+ )
89
+
90
+ if status == PacketStatus.PYTHON_VERSION_MISMATCH:
91
+ response.payload += f"\nclient python version: {sys.version}"
92
+ self._response.put(response.payload)
93
+ elif (
94
+ status == PacketStatus.HAS_CALLBACK
95
+ and response.tag in self._pending_requests
96
+ ):
97
+ self._logger.debug(f"Handling callback for request ID {status}")
98
+ callback = self._pending_requests.get(response.tag)
99
+
100
+ assert isinstance(callback, PostRequest)
101
+
102
+ try:
103
+ callback(response.payload)
104
+ except Exception as e:
105
+ self._logger.error(
106
+ f"Error in callback {callback}, which raised an exception: {e}"
107
+ )
108
+ finally:
109
+ callback.finish.set()
110
+ else:
111
+ self._response.put(response)
112
+ self._logger.debug(
113
+ f"Response for request ID {response.tag} put into response queue"
114
+ )
115
+ self._logger.info(
116
+ f"Received data: {response.payload}. from {self._host}:{self._port}"
117
+ )
118
+ except ConnectionError:
119
+ self._logger.info("Connection closed by server")
120
+ self.disconnect()
121
+ except Exception as e:
122
+ self._logger.error(f"Error receiving data: {e}")
123
+ self.disconnect()
124
+
125
+ def disconnect(self):
126
+ self._connected = False
127
+ self._logger.info("Disconnecting...")
128
+ if self._socket:
129
+ try:
130
+ self._socket.close()
131
+ self._logger.info("Socket closed successfully.")
132
+ except Exception as e:
133
+ self._logger.error(f"Error closing socket: {e}")
134
+ self._logger.info("Disconnected")
135
+
136
+ def no_pending_requests(self) -> bool:
137
+ return len(self._pending_requests) == 0
138
+
139
+ def call(
140
+ self,
141
+ request: Request,
142
+ post_request: Optional[PostRequest] = None,
143
+ timeout: float = DEFAULT_TIMEOUT,
144
+ ):
145
+ if not self._connected:
146
+ raise ConnectionError("Not connected to server")
147
+ if not isinstance(request, Request):
148
+ raise TypeError("request must be a Request instance")
149
+ if post_request is not None and not isinstance(post_request, PostRequest):
150
+ raise TypeError("post_request must be a PostRequest instance or None")
151
+
152
+ if post_request is not None:
153
+ self._logger.debug(f"Registering callback for request ID {request.tag}")
154
+ self._pending_requests[request.tag] = post_request
155
+ payload = (request, PacketStatus.HAS_CALLBACK)
156
+ else:
157
+ self._logger.debug(f"No callback for request ID {request.tag}")
158
+ payload = (request, PacketStatus.NO_CALLBACK)
159
+
160
+ self._logger.debug(f"Sending request: {request} to {self._host}:{self._port}")
161
+
162
+ socket_send(self._socket, pickle.dumps(payload), self._logger)
163
+
164
+ try:
165
+ rs = self._response.get(timeout=timeout)
166
+ except queue.Empty:
167
+ self._logger.error("Request timed out")
168
+ raise TimeoutError("Request timed out")
169
+
170
+ return rs.payload
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/python3
2
+ ############################################################################
3
+ # tools/pynuttx/gdbrpc/examples/getheaps.py
4
+ #
5
+ # SPDX-License-Identifier: Apache-2.0
6
+ #
7
+ # Licensed to the Apache Software Foundation (ASF) under one or more
8
+ # contributor license agreements. See the NOTICE file distributed with
9
+ # this work for additional information regarding copyright ownership. The
10
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
11
+ # "License"); you may not use this file except in compliance with the
12
+ # License. You may obtain a copy of the License at
13
+ #
14
+ # http://www.apache.org/licenses/LICENSE-2.0
15
+ #
16
+ # Unless required by applicable law or agreed to in writing, software
17
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
19
+ # License for the specific language governing permissions and limitations
20
+ # under the License.
21
+ #
22
+ ############################################################################
23
+
24
+ import os
25
+ import queue
26
+ import sys
27
+
28
+ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")))
29
+
30
+ import gdbrpc # noqa: E402
31
+
32
+
33
+ class Func(gdbrpc.Request):
34
+ def __init__(self):
35
+ super().__init__()
36
+
37
+ def __call__(self, q: queue.Queue):
38
+ import nxgdb
39
+
40
+ heaps = nxgdb.mm.get_heaps()
41
+ for heap in heaps:
42
+ print(heap)
43
+ q.put(list(map(str, heaps)))
44
+
45
+
46
+ if __name__ == "__main__":
47
+
48
+ client = gdbrpc.Client()
49
+
50
+ assert client.connect()
51
+
52
+ print(client.call(Func(), timeout=10))
53
+
54
+ client.disconnect()
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/python3
2
+ ############################################################################
3
+ # tools/pynuttx/gdbrpc/examples/memleak.py
4
+ #
5
+ # SPDX-License-Identifier: Apache-2.0
6
+ #
7
+ # Licensed to the Apache Software Foundation (ASF) under one or more
8
+ # contributor license agreements. See the NOTICE file distributed with
9
+ # this work for additional information regarding copyright ownership. The
10
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
11
+ # "License"); you may not use this file except in compliance with the
12
+ # License. You may obtain a copy of the License at
13
+ #
14
+ # http://www.apache.org/licenses/LICENSE-2.0
15
+ #
16
+ # Unless required by applicable law or agreed to in writing, software
17
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
19
+ # License for the specific language governing permissions and limitations
20
+ # under the License.
21
+ #
22
+ ############################################################################
23
+
24
+ import logging
25
+ import os
26
+ import queue
27
+ import sys
28
+
29
+ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")))
30
+
31
+ import gdbrpc # noqa: E402
32
+
33
+
34
+ class FetchResult(gdbrpc.PostRequest):
35
+ def __init__(self):
36
+ super().__init__()
37
+
38
+ def __call__(self, result):
39
+ print(result)
40
+
41
+
42
+ class MemLeak(gdbrpc.Request):
43
+ def __init__(self):
44
+ super().__init__()
45
+
46
+ def __call__(self, q: queue.Queue):
47
+ import gdb
48
+
49
+ q.put(gdb.execute("memleak", to_string=True))
50
+
51
+
52
+ if __name__ == "__main__":
53
+
54
+ client = gdbrpc.Client(logLevel=logging.DEBUG)
55
+
56
+ assert client.connect()
57
+
58
+ bt = FetchResult()
59
+ client.call(MemLeak(), bt)
60
+
61
+ print("Waiting for async call to complete...")
62
+
63
+ bt.finish.wait()
64
+
65
+ print("Async call completed.")
66
+
67
+ client.disconnect()