199 lines
8.0 KiB
Python
199 lines
8.0 KiB
Python
# File: cpp_python_debug/__main__.py
|
|
# Main entry point for the Cpp-Python Debug Helper application.
|
|
# This script initializes logging and starts the Tkinter GUI.
|
|
|
|
import logging
|
|
import sys
|
|
import os
|
|
|
|
# import pathlib # pathlib non è strettamente necessario qui se usiamo os.path per coerenza
|
|
|
|
# Import assoluti
|
|
from cpp_python_debug.gui.main_window import GDBGui
|
|
from cpp_python_debug.core.frozen_utils import get_app_base_path
|
|
|
|
# AppSettings non è più importato qui direttamente, GDBGui lo istanzierà.
|
|
|
|
# --- Application Constants ---
|
|
# Questi potrebbero essere definiti in un _version.py del pacchetto cpp_python_debug
|
|
# o essere statici qui.
|
|
APP_INTERNAL_NAME_FOR_PATHS = "CppPythonDebugHelper" # Nome breve per directory, ecc.
|
|
APP_DISPLAY_NAME = "Cpp-Python GDB Debug Helper"
|
|
APP_VERSION_FROM_MAIN = "1.0.1" # Versione gestita qui o da _version.py
|
|
|
|
# --- Percorsi Base e Log ---
|
|
APP_BASE_PATH = get_app_base_path() # Determina il percorso base dell'applicazione
|
|
LOG_DIR_NAME = "logs" # Nome della sottocartella per tutti i log
|
|
|
|
# Path assoluto alla directory dei log dell'applicazione
|
|
# Viene creato se non esiste.
|
|
LOG_DIRECTORY_PATH: str
|
|
try:
|
|
_potential_log_dir = os.path.join(APP_BASE_PATH, LOG_DIR_NAME)
|
|
os.makedirs(_potential_log_dir, exist_ok=True)
|
|
LOG_DIRECTORY_PATH = _potential_log_dir
|
|
except OSError as e:
|
|
# Fallback critico se non possiamo creare la directory di log primaria
|
|
print(
|
|
f"ERROR: Could not create primary log directory '{_potential_log_dir}': {e}",
|
|
file=sys.stderr,
|
|
)
|
|
user_home = os.path.expanduser("~")
|
|
fallback_log_dir = os.path.join(user_home, f".{APP_INTERNAL_NAME_FOR_PATHS}_logs")
|
|
try:
|
|
os.makedirs(fallback_log_dir, exist_ok=True)
|
|
print(
|
|
f"WARNING: Using fallback log directory: {fallback_log_dir}",
|
|
file=sys.stderr,
|
|
)
|
|
LOG_DIRECTORY_PATH = fallback_log_dir
|
|
except Exception as e_fb:
|
|
print(
|
|
f"CRITICAL ERROR: Could not create any log directory. Primary failed, Fallback failed: {e_fb}. Logging to CWD.",
|
|
file=sys.stderr,
|
|
)
|
|
LOG_DIRECTORY_PATH = os.getcwd() # Ultima risorsa disperata
|
|
|
|
# Percorso per il log specifico del dumper GDB (quello che __main__ cancella all'avvio)
|
|
# Questo è il log prodotto dallo *script precedente* gdb_dumper.py, non il suo log interno.
|
|
# Il *nuovo* gdb_dumper.py scriverà il suo log interno (gdb_dumper_script_internal.log)
|
|
# in LOG_DIRECTORY_PATH se gli viene detto dalla GDBSession.
|
|
GDB_DUMPER_LEGACY_LOG_FILENAME = (
|
|
"gdb_dumper_debug.log" # Nome del vecchio file di log del dumper
|
|
)
|
|
GDB_DUMPER_LOG_TO_DELETE = os.path.join(
|
|
LOG_DIRECTORY_PATH, GDB_DUMPER_LEGACY_LOG_FILENAME
|
|
)
|
|
|
|
|
|
def setup_global_logging():
|
|
"""
|
|
Configures basic logging for the application.
|
|
Logs to a file in LOG_DIRECTORY_PATH and to console.
|
|
"""
|
|
log_level = logging.DEBUG # Configura il livello di log desiderato
|
|
|
|
# Nome del file di log principale della GUI
|
|
main_gui_log_filename = f"{APP_INTERNAL_NAME_FOR_PATHS.lower()}_gui.log"
|
|
main_app_log_filepath = os.path.join(LOG_DIRECTORY_PATH, main_gui_log_filename)
|
|
|
|
# Configurazione base del logging
|
|
logging.basicConfig(
|
|
level=log_level,
|
|
format="%(asctime)s - %(name)-35s - %(levelname)-8s - %(message)s", # Aumentato padding per nome modulo
|
|
datefmt="%Y-%m-%d %H:%M:%S",
|
|
handlers=[
|
|
logging.FileHandler(main_app_log_filepath, mode="a", encoding="utf-8"),
|
|
logging.StreamHandler(sys.stdout), # Output anche su console
|
|
],
|
|
)
|
|
|
|
# Ottieni un logger per questo modulo (__main__) per i log iniziali
|
|
logger = logging.getLogger(
|
|
__name__
|
|
) # Equivalente a logging.getLogger("cpp_python_debug.__main__")
|
|
|
|
logger.info(
|
|
f"Global logging initialized. Log level set to: {logging.getLevelName(log_level)}."
|
|
)
|
|
logger.info(f"Application Base Path determined as: {APP_BASE_PATH}")
|
|
logger.info(f"Logging directory for all logs: {LOG_DIRECTORY_PATH}")
|
|
logger.info(f"Main GUI application log file: {main_app_log_filepath}")
|
|
|
|
# Tentativo di cancellare il vecchio log del dumper (se esiste)
|
|
# Questo si riferisce al file gdb_dumper_debug.log che il vecchio dumper scriveva.
|
|
# Il nuovo dumper scriverà gdb_dumper_script_internal.log nella stessa LOG_DIRECTORY_PATH.
|
|
if GDB_DUMPER_LOG_TO_DELETE and os.path.exists(GDB_DUMPER_LOG_TO_DELETE):
|
|
try:
|
|
os.remove(GDB_DUMPER_LOG_TO_DELETE)
|
|
logger.info(
|
|
f"Attempted to delete legacy GDB dumper log: {GDB_DUMPER_LOG_TO_DELETE} - Success."
|
|
)
|
|
except OSError as e_remove: # Più specifico di Exception
|
|
logger.warning(
|
|
f"Could not delete legacy GDB dumper log '{GDB_DUMPER_LOG_TO_DELETE}': {e_remove}"
|
|
)
|
|
else:
|
|
logger.info(
|
|
f"Legacy GDB dumper log not found (no previous log to delete): {GDB_DUMPER_LOG_TO_DELETE}"
|
|
)
|
|
logger.info(f"Starting {APP_DISPLAY_NAME} v{APP_VERSION_FROM_MAIN}")
|
|
|
|
|
|
def main():
|
|
"""
|
|
Main function to set up logging and launch the GDB GUI.
|
|
"""
|
|
# setup_global_logging() deve essere chiamato prima di qualsiasi altro log
|
|
# ma dopo che LOG_DIRECTORY_PATH è stato determinato.
|
|
# LOG_DIRECTORY_PATH è ora determinato a livello di modulo.
|
|
setup_global_logging()
|
|
|
|
app_instance_logger = logging.getLogger(
|
|
APP_INTERNAL_NAME_FOR_PATHS
|
|
) # Logger generico per l'app
|
|
|
|
if getattr(sys, "frozen", False):
|
|
app_instance_logger.info(
|
|
f"Application is running in a 'frozen' (compiled) environment."
|
|
)
|
|
app_instance_logger.info(f"Executable path: {sys.executable}")
|
|
if hasattr(sys, "_MEIPASS"): # Solo per one-file mode
|
|
app_instance_logger.info(
|
|
f"_MEIPASS temporary bundle directory: {sys._MEIPASS}"
|
|
)
|
|
else:
|
|
app_instance_logger.info(
|
|
f"Application is running in development mode (not frozen)."
|
|
)
|
|
# __file__ per __main__ quando eseguito con -m è il percorso di __main__.py
|
|
# Se eseguito come script diretto, è il percorso dello script.
|
|
app_instance_logger.info(
|
|
f"Main script __file__ location: {globals().get('__file__', 'N/A')}"
|
|
)
|
|
|
|
try:
|
|
app_instance_logger.info("Creating GDBGui instance...")
|
|
# --- MODIFICA: Passa APP_BASE_PATH e LOG_DIRECTORY_PATH a GDBGui ---
|
|
app = GDBGui(app_base_path=APP_BASE_PATH, log_directory_path=LOG_DIRECTORY_PATH)
|
|
# --- FINE MODIFICA ---
|
|
app_instance_logger.info("Starting Tkinter main event loop.")
|
|
app.mainloop()
|
|
app_instance_logger.info("Tkinter main event loop finished.")
|
|
|
|
except Exception as e:
|
|
app_instance_logger.critical(
|
|
f"An unhandled critical error occurred in main: {e}", exc_info=True
|
|
)
|
|
try:
|
|
# Tenta di mostrare un messagebox di errore
|
|
import tkinter as tk
|
|
from tkinter import messagebox
|
|
|
|
root_for_error = None
|
|
if not tk._default_root: # type: ignore # Evita di creare un root se uno esiste già da un'eccezione in Tk
|
|
root_for_error = tk.Tk()
|
|
root_for_error.withdraw() # Nascondi la finestra root extra
|
|
|
|
messagebox.showerror(
|
|
"Critical Application Error",
|
|
f"A critical error occurred:\n{e}\n\nPlease check logs in '{LOG_DIRECTORY_PATH}' for details.",
|
|
)
|
|
if root_for_error:
|
|
root_for_error.destroy()
|
|
except Exception as e_tk_critical:
|
|
# Se anche Tkinter fallisce, logga sulla console di emergenza (stderr)
|
|
print(
|
|
f"CRITICAL_TKINTER_ERROR: Could not display error messagebox: {e_tk_critical}",
|
|
file=sys.stderr,
|
|
)
|
|
print(f"Original critical error was: {e}", file=sys.stderr)
|
|
|
|
finally:
|
|
app_instance_logger.info(f"{APP_DISPLAY_NAME} is shutting down.")
|
|
logging.shutdown() # Chiude tutti gli handler di logging in modo pulito
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|