Skip to content

Commit e4da5fc

Browse files
committed
Debug: color logging in apps/furi gdb helper, check and show crash message in gdb console.
1 parent 4b5a013 commit e4da5fc

File tree

1 file changed

+58
-14
lines changed

1 file changed

+58
-14
lines changed

scripts/debug/flipperapps.py

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,33 @@
77
import gdb
88

99

10+
class bcolors:
11+
HEADER = "\033[95m"
12+
OKBLUE = "\033[94m"
13+
OKCYAN = "\033[96m"
14+
OKGREEN = "\033[92m"
15+
WARNING = "\033[93m"
16+
FAIL = "\033[91m"
17+
ENDC = "\033[0m"
18+
BOLD = "\033[1m"
19+
UNDERLINE = "\033[4m"
20+
21+
22+
LOG_PREFIX = "[FURI]"
23+
24+
25+
def error(line):
26+
print(f"{bcolors.FAIL}{LOG_PREFIX} {line}{bcolors.ENDC}")
27+
28+
29+
def warning(line):
30+
print(f"{bcolors.WARNING}{LOG_PREFIX} {line}{bcolors.ENDC}")
31+
32+
33+
def info(line):
34+
print(f"{bcolors.OKGREEN}{LOG_PREFIX} {line}{bcolors.ENDC}")
35+
36+
1037
def get_file_crc32(filename):
1138
with open(filename, "rb") as f:
1239
return zlib.crc32(f.read())
@@ -39,20 +66,20 @@ def get_original_elf_path(self) -> str:
3966
def is_debug_available(self) -> bool:
4067
have_debug_info = bool(self.debug_link_elf and self.debug_link_crc)
4168
if not have_debug_info:
42-
print("No debug info available for this app")
69+
warning("No debug info available for this app")
4370
return False
4471
debug_elf_path = self.get_original_elf_path()
4572
debug_elf_crc32 = get_file_crc32(debug_elf_path)
4673
if self.debug_link_crc != debug_elf_crc32:
47-
print(
74+
warning(
4875
f"Debug info ({debug_elf_path}) CRC mismatch: {self.debug_link_crc:08x} != {debug_elf_crc32:08x}, rebuild app"
4976
)
5077
return False
5178
return True
5279

5380
def get_gdb_load_command(self) -> str:
5481
load_path = self.get_original_elf_path()
55-
print(f"Loading debug information from {load_path}")
82+
info(f"Loading debug information from {load_path}")
5683
load_command = (
5784
f"add-symbol-file -readnow {load_path} 0x{self.text_address:08x} "
5885
)
@@ -121,12 +148,12 @@ def invoke(self, arg, from_tty):
121148
AppState.DEBUG_ELF_ROOT = arg
122149
try:
123150
global helper
124-
print(f"Set '{arg}' as debug info lookup path for Flipper external apps")
151+
info(f"Set '{arg}' as debug info lookup path for Flipper external apps")
125152
helper.attach_to_fw()
126153
gdb.events.stop.connect(helper.handle_stop)
127154
gdb.events.gdb_exiting.connect(helper.handle_exit)
128155
except gdb.error as e:
129-
print(f"Support for Flipper external apps debug is not available: {e}")
156+
error(f"Support for Flipper external apps debug is not available: {e}")
130157

131158

132159
class FlipperAppStateHelper:
@@ -148,13 +175,29 @@ def _exec_gdb_command(self, command: str) -> bool:
148175
gdb.execute(command)
149176
return True
150177
except gdb.error as e:
151-
print(f"Failed to execute GDB command '{command}': {e}")
178+
error(f"Failed to execute GDB command '{command}': {e}")
152179
return False
153180

181+
def _get_crash_message(self):
182+
message = self.app_check_message.value()
183+
if message == 1:
184+
return "furi_assert failed"
185+
elif message == 2:
186+
return "furi_check failed"
187+
else:
188+
return message
189+
154190
def _sync_apps(self) -> None:
191+
crash_message = self._get_crash_message()
192+
if crash_message:
193+
crash_message = f"! System crashed: {crash_message} !"
194+
error("!" * len(crash_message))
195+
error(crash_message)
196+
error("!" * len(crash_message))
197+
155198
self.set_debug_mode(True)
156199
if not (app_list := self.app_list_ptr.value()):
157-
print("Reset app loader state")
200+
info("Reset app loader state")
158201
for app in self._current_apps:
159202
self._exec_gdb_command(app.get_gdb_unload_command())
160203
self._current_apps = []
@@ -167,22 +210,23 @@ def _sync_apps(self) -> None:
167210

168211
for app in self._current_apps.copy():
169212
if app.entry_address not in loaded_apps:
170-
print(f"Application {app.name} is no longer loaded")
213+
warning(f"Application {app.name} is no longer loaded")
171214
if not self._exec_gdb_command(app.get_gdb_unload_command()):
172-
print(f"Failed to unload debug info for {app.name}")
215+
error(f"Failed to unload debug info for {app.name}")
173216
self._current_apps.remove(app)
174217

175218
for entry_point, app in loaded_apps.items():
176219
if entry_point not in set(app.entry_address for app in self._current_apps):
177220
new_app_state = AppState.from_gdb(app)
178-
print(f"New application loaded. Adding debug info")
221+
warning(f"New application loaded. Adding debug info")
179222
if self._exec_gdb_command(new_app_state.get_gdb_load_command()):
180223
self._current_apps.append(new_app_state)
181224
else:
182-
print(f"Failed to load debug info for {new_app_state}")
225+
error(f"Failed to load debug info for {new_app_state}")
183226

184227
def attach_to_fw(self) -> None:
185-
print("Attaching to Flipper firmware")
228+
info("Attaching to Flipper firmware")
229+
self.app_check_message = gdb.lookup_global_symbol("__furi_check_message")
186230
self.app_list_ptr = gdb.lookup_global_symbol(
187231
"flipper_application_loaded_app_list"
188232
)
@@ -200,10 +244,10 @@ def set_debug_mode(self, mode: bool) -> None:
200244
try:
201245
gdb.execute(f"set variable furi_hal_debug_gdb_session_active = {int(mode)}")
202246
except gdb.error as e:
203-
print(f"Failed to set debug mode: {e}")
247+
error(f"Failed to set debug mode: {e}")
204248

205249

206250
# Init additional 'fap-set-debug-elf-root' command and set up hooks
207251
SetFapDebugElfRoot()
208252
helper = FlipperAppStateHelper()
209-
print("Support for Flipper external apps debug is loaded")
253+
info("Support for Flipper external apps debug is loaded")

0 commit comments

Comments
 (0)