2025-08-26 20:22:11 -05:00
// SPDX-FileCopyrightText: 2021 Ernie Pasveer <epasveer@att.net>
2025-08-26 17:26:05 -05:00
//
// SPDX-License-Identifier: GPL-3.0-or-later
2021-09-01 13:58:59 -05:00
# include "SeerMainWindow.h"
2021-10-03 10:34:50 -05:00
# include "SeerUtl.h"
2023-07-31 13:29:59 -05:00
# include "QProcessInfo.h"
2021-09-01 13:58:59 -05:00
# include <QtWidgets/QApplication>
2025-09-15 16:44:05 -05:00
# include <QtWidgets/QStyleFactory>
2021-09-25 16:00:09 -05:00
# include <QtGui/QIcon>
2021-09-01 13:58:59 -05:00
# include <QtCore/QCommandLineParser>
# include <QtCore/QCommandLineOption>
# include <QtCore/QStringList>
# include <QtCore/QString>
2023-04-17 17:53:28 -05:00
# include <QtCore/QTextStream>
# include <QtCore/QObject>
2022-01-20 10:40:56 -06:00
# include <QtCore/QDebug>
2025-09-15 16:44:05 -05:00
# include <QtCore/QDirIterator>
2023-04-17 17:53:28 -05:00
# include <iostream>
static void seerhelp ( ) {
QString text ;
QString fileName ( " :/seer/resources/help/seergdb.hlp " ) ;
QFile file ( fileName ) ;
if ( file . open ( QIODevice : : ReadOnly ) = = false ) {
text = " seer: no help available. \n " ;
} else {
text = file . readAll ( ) ;
}
file . close ( ) ;
QTextStream ( stdout ) < < text ;
exit ( 0 ) ;
}
2021-09-01 13:58:59 -05:00
int main ( int argc , char * argv [ ] ) {
2022-03-26 08:43:24 -05:00
//
// Set up logging and message formats.
//
QLoggingCategory : : setFilterRules ( " *.debug=false \n "
" *.info=false \n "
" *.warning=false \n "
" *.critical=true " ) ;
2022-03-26 08:33:45 -05:00
qSetMessagePattern ( " [%{time hh:mm:ss}][%{function}:%{line}][%{category}] %{message} " ) ;
2022-01-20 10:40:56 -06:00
2022-03-26 08:43:24 -05:00
//
// Create the app.
//
2021-09-01 13:58:59 -05:00
QApplication app ( argc , argv ) ;
2022-08-25 17:56:18 -05:00
QCoreApplication : : setApplicationName ( " seergdb " ) ;
QCoreApplication : : setOrganizationName ( " seergdb " ) ;
2025-09-20 15:56:10 -05:00
QCoreApplication : : setApplicationVersion ( Seer : : version ( ) + " - Ernie Pasveer (c)2021 - 2025 " ) ;
2021-09-01 13:58:59 -05:00
//
// Parse arguments.
//
QCommandLineParser parser ;
parser . setApplicationDescription ( " \n Seer - A gui frontend for gdb. " ) ;
parser . setOptionsAfterPositionalArgumentsMode ( QCommandLineParser : : ParseAsPositionalArguments ) ; // Treat all arguments after the executable name as positional arguments too.
parser . setSingleDashWordOptionMode ( QCommandLineParser : : ParseAsLongOptions ) ; // Treat all arguments long options.
parser . addVersionOption ( ) ;
// Run or start options.
2023-04-17 17:53:28 -05:00
QCommandLineOption runOption ( QStringList ( ) < < " r " < < " run " ) ;
2021-09-01 13:58:59 -05:00
parser . addOption ( runOption ) ;
2023-04-17 17:53:28 -05:00
QCommandLineOption startOption ( QStringList ( ) < < " s " < < " start " ) ;
2021-09-01 13:58:59 -05:00
parser . addOption ( startOption ) ;
2023-04-20 13:27:52 -05:00
QCommandLineOption attachOption ( QStringList ( ) < < " attach " , " " , " pid " ) ;
2021-09-01 13:58:59 -05:00
parser . addOption ( attachOption ) ;
2023-04-20 13:27:52 -05:00
QCommandLineOption connectOption ( QStringList ( ) < < " connect " , " " , " medium " ) ;
2021-09-01 13:58:59 -05:00
parser . addOption ( connectOption ) ;
2023-04-20 13:27:52 -05:00
QCommandLineOption rrOption ( QStringList ( ) < < " rr " , " " , " hostport " ) ;
2023-04-15 12:36:28 -05:00
parser . addOption ( rrOption ) ;
2023-04-20 13:27:52 -05:00
QCommandLineOption corefileOption ( QStringList ( ) < < " core " , " " , " corefile " ) ;
2021-09-01 13:58:59 -05:00
parser . addOption ( corefileOption ) ;
2023-04-20 13:27:52 -05:00
QCommandLineOption projectOption ( QStringList ( ) < < " project " , " " , " project " ) ;
2023-02-11 10:41:43 -06:00
parser . addOption ( projectOption ) ;
2023-04-17 17:53:28 -05:00
QCommandLineOption configOption ( QStringList ( ) < < " config " ) ;
2022-06-16 19:25:05 -05:00
parser . addOption ( configOption ) ;
2023-12-15 17:02:31 -06:00
QCommandLineOption workingdirOption ( QStringList ( ) < < " cwd " < < " working-dir " , " " , " workingdirectory " ) ;
parser . addOption ( workingdirOption ) ;
2023-04-20 13:27:52 -05:00
QCommandLineOption symbolfileOption ( QStringList ( ) < < " sym " < < " symbol-file " , " " , " symbolfile " ) ;
2023-04-17 17:53:28 -05:00
parser . addOption ( symbolfileOption ) ;
2023-04-20 13:27:52 -05:00
QCommandLineOption breakfileOption ( QStringList ( ) < < " bl " < < " break-load " , " " , " breakpointfile " ) ;
2023-04-17 17:53:28 -05:00
parser . addOption ( breakfileOption ) ;
2023-04-20 13:27:52 -05:00
QCommandLineOption breakfunctionOption ( QStringList ( ) < < " bf " < < " break-function " , " " , " breakpointfunction " ) ;
2023-04-17 17:53:28 -05:00
parser . addOption ( breakfunctionOption ) ;
2023-11-25 09:21:39 -06:00
QCommandLineOption breaksourceOption ( QStringList ( ) < < " bs " < < " break-source " , " " , " breakpointsource " ) ;
parser . addOption ( breaksourceOption ) ;
2024-10-13 11:27:56 -05:00
QCommandLineOption showAssemblyTabOption ( QStringList ( ) < < " sat " < < " show-assembly-tab " , " " , " showassemblytab " ) ;
2023-04-17 17:53:28 -05:00
parser . addOption ( showAssemblyTabOption ) ;
2024-10-13 11:27:56 -05:00
QCommandLineOption startAddressRandomizeOption ( QStringList ( ) < < " sar " < < " start-address-randomize " , " " , " startaddressrandomize " ) ;
2023-04-17 17:53:28 -05:00
parser . addOption ( startAddressRandomizeOption ) ;
2024-10-13 11:27:56 -05:00
QCommandLineOption nonStopModeOption ( QStringList ( ) < < " nsm " < < " non-stop-mode " , " " , " nonstopmode " ) ;
2023-04-17 17:53:28 -05:00
parser . addOption ( nonStopModeOption ) ;
2023-09-11 17:44:49 -05:00
QCommandLineOption gdbProgramOption ( QStringList ( ) < < " gdb-program " , " " , " gdbprogram " ) ;
parser . addOption ( gdbProgramOption ) ;
QCommandLineOption gdbArgumentsOption ( QStringList ( ) < < " gdb-arguments " , " " , " gdbarguments " ) ;
parser . addOption ( gdbArgumentsOption ) ;
2025-09-15 16:44:05 -05:00
QCommandLineOption xxxdebugOption ( QStringList ( ) < < " xxx-debug " ) ;
2024-11-25 12:40:30 -06:00
parser . addOption ( xxxdebugOption ) ;
2022-09-18 13:11:15 -05:00
2025-09-15 16:44:05 -05:00
QCommandLineOption xxxresourcesOption ( QStringList ( ) < < " xxx-resources " ) ;
parser . addOption ( xxxresourcesOption ) ;
QCommandLineOption xxxstylesOption ( QStringList ( ) < < " xxx-styles " ) ;
parser . addOption ( xxxstylesOption ) ;
2023-04-17 17:53:28 -05:00
QCommandLineOption helpOption ( QStringList ( ) < < " h " < < " help " ) ;
parser . addOption ( helpOption ) ;
2021-09-01 13:58:59 -05:00
// A positional argument for executable name.
// All other arguments after that are treated as positional arguments for the executable.
2023-04-20 13:27:52 -05:00
parser . addPositionalArgument ( " executableandarguments " , " " ) ;
2021-09-01 13:58:59 -05:00
// Process the arguments.
parser . process ( app ) ;
2023-04-17 17:53:28 -05:00
if ( parser . isSet ( helpOption ) ) {
seerhelp ( ) ;
}
2024-11-25 12:40:30 -06:00
if ( parser . isSet ( xxxdebugOption ) ) {
2022-09-18 13:11:15 -05:00
QLoggingCategory : : setFilterRules ( " *.debug=false \n "
" *.info=false \n "
" *.warning=false \n "
" *.critical=true \n "
" default.debug=true " ) ;
2024-11-25 12:40:30 -06:00
QSettings settings ;
qDebug ( ) < < " SETTINGS " < < settings . fileName ( ) ;
2022-09-18 13:11:15 -05:00
}
2025-09-15 16:44:05 -05:00
if ( parser . isSet ( xxxresourcesOption ) ) {
QTextStream ( stdout ) < < " RESOURCES " < < " \n " ;
QDirIterator it ( " : " , QDirIterator : : Subdirectories ) ;
while ( it . hasNext ( ) ) {
QTextStream ( stdout ) < < " " < < it . next ( ) < < " \n " ;
}
QTextStream ( stdout ) < < " ENDRESOURCES " < < " \n " ;
return 0 ;
}
if ( parser . isSet ( xxxstylesOption ) ) {
QTextStream ( stdout ) < < " STYLES " < < " \n " ;
QStringList styles = QStyleFactory : : keys ( ) ;
for ( auto style : styles ) {
QTextStream ( stdout ) < < " " < < style < < " \n " ;
}
QTextStream ( stdout ) < < " ENDSTYLES " < < " \n " ;
return 0 ;
}
2021-09-01 13:58:59 -05:00
// Get the positional arguments. (The ones at the end of the line - executable name and its arguments.
QStringList positionalArguments = parser . positionalArguments ( ) ;
// Get the executable name from the arguments;
QString executableName ;
if ( positionalArguments . size ( ) > 0 ) {
executableName = positionalArguments . takeFirst ( ) ;
}
// Get launch mode.
QString launchMode = " none " ;
2022-07-30 12:02:52 -05:00
QString breakMode = " none " ;
2021-09-01 13:58:59 -05:00
int executablePid = - 1 ;
2023-04-15 12:36:28 -05:00
QString executableConnectHostPort ;
2023-09-03 22:19:45 -05:00
QString executableRRTraceDirectory ;
2023-12-15 17:02:31 -06:00
QString executableWorkingDirectory ;
2022-12-29 19:03:18 -06:00
QString executableSymbolFilename ;
2022-03-26 10:29:53 -05:00
QString executableBreakpointsFilename ;
2022-07-31 11:20:38 -05:00
QString executableBreakpointFunctionName ;
2023-11-26 14:06:32 -06:00
QString executableBreakpointSourceFilenameAndLineno ;
2022-07-31 11:20:38 -05:00
QString executableShowAssemblyTab ;
QString executableStartAddressRandomize ;
2022-10-01 15:41:50 -05:00
QString executableNonStopMode ;
2021-09-01 13:58:59 -05:00
QString executableCoreFilename ;
2023-02-11 10:41:43 -06:00
QString projectFilename ;
2023-09-11 17:44:49 -05:00
QString gdbProgram ;
QString gdbArguments ;
2021-09-01 13:58:59 -05:00
if ( parser . isSet ( runOption ) ) {
launchMode = " run " ;
2022-07-30 12:02:52 -05:00
breakMode = " none " ;
2021-09-01 13:58:59 -05:00
}
if ( parser . isSet ( startOption ) ) {
2022-07-30 12:02:52 -05:00
launchMode = " run " ;
breakMode = " inmain " ;
2021-09-01 13:58:59 -05:00
}
2023-12-15 17:02:31 -06:00
if ( parser . isSet ( workingdirOption ) ) {
executableWorkingDirectory = parser . value ( workingdirOption ) ;
}
2022-12-29 19:03:18 -06:00
if ( parser . isSet ( symbolfileOption ) ) {
executableSymbolFilename = parser . value ( symbolfileOption ) ;
}
2022-07-31 11:20:38 -05:00
if ( parser . isSet ( breakfileOption ) ) {
executableBreakpointsFilename = parser . value ( breakfileOption ) ;
}
if ( parser . isSet ( breakfunctionOption ) ) {
executableBreakpointFunctionName = parser . value ( breakfunctionOption ) ;
breakMode = " infunction " ;
}
2023-11-26 14:06:32 -06:00
if ( parser . isSet ( breaksourceOption ) ) {
executableBreakpointSourceFilenameAndLineno = parser . value ( breaksourceOption ) ;
2023-11-25 09:21:39 -06:00
breakMode = " insource " ;
}
2022-07-31 11:20:38 -05:00
if ( parser . isSet ( showAssemblyTabOption ) ) {
executableShowAssemblyTab = parser . value ( showAssemblyTabOption ) ;
}
if ( parser . isSet ( startAddressRandomizeOption ) ) {
executableStartAddressRandomize = parser . value ( startAddressRandomizeOption ) ;
2022-03-26 10:29:53 -05:00
}
2022-10-01 15:41:50 -05:00
if ( parser . isSet ( nonStopModeOption ) ) {
executableNonStopMode = parser . value ( nonStopModeOption ) ;
}
2021-09-01 13:58:59 -05:00
if ( parser . isSet ( attachOption ) ) {
launchMode = " attach " ;
QString pid = parser . value ( attachOption ) ;
executablePid = pid . toInt ( ) ;
2023-07-31 13:29:59 -05:00
if ( executableName = = " " ) {
QProcessInfo info = QProcessInfo : : populate ( executablePid ) ;
executableName = info . path ( ) + " / " + info . name ( ) ;
}
2021-09-01 13:58:59 -05:00
}
2022-06-16 19:25:05 -05:00
if ( parser . isSet ( connectOption ) ) {
launchMode = " connect " ;
2023-04-15 12:36:28 -05:00
executableConnectHostPort = parser . value ( connectOption ) ;
}
if ( parser . isSet ( rrOption ) ) {
launchMode = " rr " ;
2023-09-03 22:19:45 -05:00
executableRRTraceDirectory = parser . value ( rrOption ) ;
2022-06-16 19:25:05 -05:00
}
2021-09-01 13:58:59 -05:00
if ( parser . isSet ( corefileOption ) ) {
launchMode = " corefile " ;
executableCoreFilename = parser . value ( corefileOption ) ;
}
2023-02-11 10:41:43 -06:00
if ( parser . isSet ( projectOption ) ) {
launchMode = " project " ;
projectFilename = parser . value ( projectOption ) ;
}
2022-06-16 19:25:05 -05:00
if ( parser . isSet ( configOption ) ) {
launchMode = " configdialog " ;
2021-09-01 13:58:59 -05:00
}
2023-09-11 17:44:49 -05:00
if ( parser . isSet ( gdbProgramOption ) ) {
gdbProgram = parser . value ( gdbProgramOption ) ;
}
if ( parser . isSet ( gdbArgumentsOption ) ) {
gdbArguments = parser . value ( gdbArgumentsOption ) ;
}
2022-06-16 19:25:05 -05:00
2021-09-01 13:58:59 -05:00
//
// Start Seer
//
SeerMainWindow seer ;
2025-12-16 09:42:08 -06:00
seer . setWindowIcon ( QIcon ( " :/seer/resources/icons/hicolor/64x64/seergdb.png " ) ) ;
2021-09-01 13:58:59 -05:00
seer . setExecutableName ( executableName ) ;
2023-12-15 17:02:31 -06:00
seer . setExecutableWorkingDirectory ( executableWorkingDirectory ) ;
2022-12-29 19:03:18 -06:00
seer . setExecutableSymbolName ( executableSymbolFilename ) ;
2021-09-01 13:58:59 -05:00
seer . setExecutableArguments ( positionalArguments ) ;
2022-07-31 11:20:38 -05:00
if ( executableBreakpointsFilename ! = " " ) {
seer . setExecutableBreakpointsFilename ( executableBreakpointsFilename ) ;
}
if ( executableBreakpointFunctionName ! = " " ) {
seer . setExecutableBreakpointFunctionName ( executableBreakpointFunctionName ) ;
}
2023-11-26 14:06:32 -06:00
if ( executableBreakpointSourceFilenameAndLineno ! = " " ) {
seer . setExecutableBreakpointSourceName ( executableBreakpointSourceFilenameAndLineno ) ;
2023-11-25 09:21:39 -06:00
}
2022-07-31 11:20:38 -05:00
if ( executableShowAssemblyTab ! = " " ) {
if ( executableShowAssemblyTab = = " yes " ) {
seer . setExecutableShowAssemblyTab ( true ) ;
} else if ( executableShowAssemblyTab = = " no " ) {
seer . setExecutableShowAssemblyTab ( false ) ;
} else {
printf ( " %s: Unknown --show-assembly-tab option '%s' \n " , qPrintable ( QCoreApplication : : applicationName ( ) ) , qPrintable ( executableShowAssemblyTab ) ) ;
return 1 ;
}
}
if ( executableStartAddressRandomize ! = " " ) {
if ( executableStartAddressRandomize = = " yes " ) {
seer . setExecutableRandomizeStartAddress ( true ) ;
} else if ( executableStartAddressRandomize = = " no " ) {
seer . setExecutableRandomizeStartAddress ( false ) ;
} else {
printf ( " %s: Unknown --start-address-randomize option '%s' \n " , qPrintable ( QCoreApplication : : applicationName ( ) ) , qPrintable ( executableStartAddressRandomize ) ) ;
return 1 ;
}
}
2022-10-01 15:41:50 -05:00
if ( executableNonStopMode ! = " " ) {
if ( executableNonStopMode = = " yes " ) {
seer . setExecutableNonStopMode ( true ) ;
} else if ( executableNonStopMode = = " no " ) {
seer . setExecutableNonStopMode ( false ) ;
} else {
printf ( " %s: Unknown --non-stop-mode option '%s' \n " , qPrintable ( QCoreApplication : : applicationName ( ) ) , qPrintable ( executableNonStopMode ) ) ;
return 1 ;
}
}
2023-09-11 17:44:49 -05:00
if ( gdbProgram ! = " " ) {
seer . setGdbProgramOverride ( gdbProgram ) ;
}
if ( gdbArguments ! = " " ) {
seer . setGdbArgumentsOverride ( gdbArguments ) ;
}
2023-04-20 13:27:52 -05:00
qDebug ( ) < < " EXECUTABLENAME " < < executableName ;
2023-12-15 17:02:31 -06:00
qDebug ( ) < < " WORKINGDIRECTORY " < < executableWorkingDirectory ;
2023-04-20 13:27:52 -05:00
qDebug ( ) < < " SYMBOLNAME " < < executableSymbolFilename ;
qDebug ( ) < < " PID " < < executablePid ;
qDebug ( ) < < " CONNECTHOST " < < executableConnectHostPort ;
2023-09-03 22:19:45 -05:00
qDebug ( ) < < " RRTRACEDIRECTORY " < < executableRRTraceDirectory ;
2023-04-20 13:27:52 -05:00
qDebug ( ) < < " COREFILENAME " < < executableCoreFilename ;
qDebug ( ) < < " PROJECTFILE " < < projectFilename ;
qDebug ( ) < < " ARGUMENTS " < < positionalArguments ;
2021-09-01 13:58:59 -05:00
seer . setExecutablePid ( executablePid ) ;
2023-04-15 12:36:28 -05:00
seer . setExecutableConnectHostPort ( executableConnectHostPort ) ;
2023-09-03 22:19:45 -05:00
seer . setExecutableRRTraceDirectory ( executableRRTraceDirectory ) ;
2021-09-01 13:58:59 -05:00
seer . setExecutableCoreFilename ( executableCoreFilename ) ;
2023-02-11 10:41:43 -06:00
seer . setProjectFilename ( projectFilename ) ;
2021-09-01 13:58:59 -05:00
2022-07-30 12:02:52 -05:00
seer . launchExecutable ( launchMode , breakMode ) ;
2021-09-01 13:58:59 -05:00
seer . show ( ) ;
2023-09-04 15:25:40 -05:00
seer . activateWindow ( ) ;
2021-09-01 13:58:59 -05:00
return app . exec ( ) ;
}