1414
1515package com .espressif .idf .debug .gdbjtag .openocd ;
1616
17+ import java .io .BufferedReader ;
18+ import java .io .IOException ;
1719import java .util .ArrayList ;
1820import java .util .List ;
21+ import java .util .concurrent .TimeUnit ;
22+ import java .util .regex .Matcher ;
23+ import java .util .regex .Pattern ;
1924
2025import org .eclipse .cdt .core .settings .model .ICConfigurationDescription ;
2126import org .eclipse .cdt .debug .gdbjtag .core .IGDBJtagConstants ;
2429import org .eclipse .cdt .dsf .gdb .internal .GdbPlugin ;
2530import org .eclipse .core .resources .IProject ;
2631import org .eclipse .core .runtime .CoreException ;
32+ import org .eclipse .core .runtime .IStatus ;
2733import org .eclipse .core .runtime .Platform ;
34+ import org .eclipse .core .runtime .Status ;
2835import org .eclipse .debug .core .ILaunchConfiguration ;
2936import org .eclipse .debug .core .ILaunchConfigurationWorkingCopy ;
3037import org .eclipse .embedcdt .core .EclipseUtils ;
@@ -89,11 +96,17 @@ public static String[] getGdbServerCommandLineArray(ILaunchConfiguration configu
8996 return null ;
9097
9198 String executable = getGdbServerCommand (configuration , null );
92- if (executable == null || executable .length () == 0 )
99+ if (executable == null || executable .isEmpty () )
93100 return null ;
94101
102+
95103 lst .add (executable );
96104
105+ boolean useModernSyntax = useModernPortSyntax (executable );
106+ String fmtGdbPort = useModernSyntax ? "gdb port %d" : "gdb_port %d" ; //$NON-NLS-1$ //$NON-NLS-2$
107+ String fmtTelnetPort = useModernSyntax ? "telnet port %d" : "telnet_port %d" ; //$NON-NLS-1$ //$NON-NLS-2$
108+ String fmtTclPort = useModernSyntax ? "tcl port %d" : "tcl_port %d" ; //$NON-NLS-1$ //$NON-NLS-2$
109+
97110 int port = PortChecker
98111 .getAvailablePort (DefaultPreferences .GDB_SERVER_GDB_PORT_NUMBER_DEFAULT );
99112
@@ -102,21 +115,21 @@ public static String[] getGdbServerCommandLineArray(ILaunchConfiguration configu
102115 configurationWorkingCopy .doSave ();
103116
104117 lst .add ("-c" ); //$NON-NLS-1$
105- lst .add ("gdb_port " + port ); //$NON-NLS-1$
118+ lst .add (String . format ( fmtGdbPort , port ));
106119
107120 port = PortChecker
108121 .getAvailablePort (configuration .getAttribute (ConfigurationAttributes .GDB_SERVER_TELNET_PORT_NUMBER ,
109122 DefaultPreferences .GDB_SERVER_TELNET_PORT_NUMBER_DEFAULT ));
110123
111124 lst .add ("-c" ); //$NON-NLS-1$
112- lst .add ("telnet_port " + port ); //$NON-NLS-1$
125+ lst .add (String . format ( fmtTelnetPort , port ));
113126
114127 port = PortChecker .getAvailablePort (
115128 Integer .parseInt (configuration .getAttribute (ConfigurationAttributes .GDB_SERVER_TCL_PORT_NUMBER ,
116129 DefaultPreferences .GDB_SERVER_TCL_PORT_NUMBER_DEFAULT )));
117130
118131 lst .add ("-c" ); //$NON-NLS-1$
119- lst .add ("tcl_port " + port ); //$NON-NLS-1$
132+ lst .add (String . format ( fmtTclPort , port ));
120133
121134 String other = configuration
122135 .getAttribute (ConfigurationAttributes .GDB_SERVER_OTHER , DefaultPreferences .GDB_SERVER_OTHER_DEFAULT )
@@ -322,4 +335,56 @@ public static boolean getDoStartGdbClient(ILaunchConfiguration config) throws Co
322335 }
323336
324337 // ------------------------------------------------------------------------
338+
339+ private static boolean useModernPortSyntax (String executablePath )
340+ {
341+ if (executablePath == null || executablePath .isEmpty ())
342+ {
343+ return false ;
344+ }
345+ Pattern outputPattern = Pattern .compile ("(?:Open On-Chip Debugger |v)(?<major>\\ d+)\\ .(?<minor>\\ d+)" ); //$NON-NLS-1$
346+
347+ try
348+ {
349+ ProcessBuilder pb = new ProcessBuilder (executablePath , "--version" ); //$NON-NLS-1$
350+ pb .redirectErrorStream (true );
351+ Process process = pb .start ();
352+
353+ try
354+ {
355+ if (!process .waitFor (2 , TimeUnit .SECONDS ))
356+ {
357+ return false ;
358+ }
359+
360+ try (BufferedReader reader = process .inputReader ())
361+ {
362+ return reader .lines ().map (outputPattern ::matcher ).filter (Matcher ::find ).findFirst ().map (matcher -> {
363+ int major = Integer .parseInt (matcher .group ("major" )); //$NON-NLS-1$
364+ int minor = Integer .parseInt (matcher .group ("minor" )); //$NON-NLS-1$
365+ return major > 0 || (major == 0 && minor >= 12 );
366+ }).orElse (false );
367+ }
368+ } finally
369+ {
370+ if (process .isAlive ())
371+ {
372+ process .destroyForcibly ();
373+ }
374+ }
375+ }
376+ catch (IOException e )
377+ {
378+ Activator .log (new CoreException (new Status (IStatus .WARNING , Activator .PLUGIN_ID ,
379+ "Failed to execute or parse OpenOCD version fallback for path: " + executablePath , e ))); //$NON-NLS-1$
380+ return false ;
381+ }
382+ catch (InterruptedException e )
383+ {
384+ Thread .currentThread ().interrupt ();
385+ Activator .log (new CoreException (new Status (IStatus .WARNING , Activator .PLUGIN_ID ,
386+ "Thread was interrupted while waiting for OpenOCD process to exit." , e ))); //$NON-NLS-1$
387+ return false ;
388+ }
389+ }
325390}
0 commit comments