@@ -10,6 +10,7 @@ mod tests;
10
10
11
11
pub mod common;
12
12
pub mod compute_diff;
13
+ mod debuggers;
13
14
pub mod errors;
14
15
pub mod header;
15
16
mod json;
@@ -36,8 +37,8 @@ use walkdir::WalkDir;
36
37
37
38
use self :: header:: { EarlyProps , make_test_description} ;
38
39
use crate :: common:: {
39
- Config , Debugger , Mode , PassMode , TestPaths , UI_EXTENSIONS , expected_output_path,
40
- output_base_dir , output_relative_path,
40
+ Config , Mode , PassMode , TestPaths , UI_EXTENSIONS , expected_output_path, output_base_dir ,
41
+ output_relative_path,
41
42
} ;
42
43
use crate :: header:: HeadersCache ;
43
44
use crate :: util:: logv;
@@ -204,9 +205,11 @@ pub fn parse_config(args: Vec<String>) -> Config {
204
205
205
206
let target = opt_str2 ( matches. opt_str ( "target" ) ) ;
206
207
let android_cross_path = opt_path ( matches, "android-cross-path" ) ;
207
- let ( cdb, cdb_version) = analyze_cdb ( matches. opt_str ( "cdb" ) , & target) ;
208
- let ( gdb, gdb_version) = analyze_gdb ( matches. opt_str ( "gdb" ) , & target, & android_cross_path) ;
209
- let lldb_version = matches. opt_str ( "lldb-version" ) . as_deref ( ) . and_then ( extract_lldb_version) ;
208
+ let ( cdb, cdb_version) = debuggers:: analyze_cdb ( matches. opt_str ( "cdb" ) , & target) ;
209
+ let ( gdb, gdb_version) =
210
+ debuggers:: analyze_gdb ( matches. opt_str ( "gdb" ) , & target, & android_cross_path) ;
211
+ let lldb_version =
212
+ matches. opt_str ( "lldb-version" ) . as_deref ( ) . and_then ( debuggers:: extract_lldb_version) ;
210
213
let color = match matches. opt_str ( "color" ) . as_deref ( ) {
211
214
Some ( "auto" ) | None => ColorConfig :: AutoColor ,
212
215
Some ( "always" ) => ColorConfig :: AlwaysColor ,
@@ -443,9 +446,9 @@ pub fn run_tests(config: Arc<Config>) {
443
446
if let Mode :: DebugInfo = config. mode {
444
447
// Debugging emscripten code doesn't make sense today
445
448
if !config. target . contains ( "emscripten" ) {
446
- configs. extend ( configure_cdb ( & config) ) ;
447
- configs. extend ( configure_gdb ( & config) ) ;
448
- configs. extend ( configure_lldb ( & config) ) ;
449
+ configs. extend ( debuggers :: configure_cdb ( & config) ) ;
450
+ configs. extend ( debuggers :: configure_gdb ( & config) ) ;
451
+ configs. extend ( debuggers :: configure_lldb ( & config) ) ;
449
452
}
450
453
} else {
451
454
configs. push ( config. clone ( ) ) ;
@@ -498,62 +501,6 @@ pub fn run_tests(config: Arc<Config>) {
498
501
}
499
502
}
500
503
501
- fn configure_cdb ( config : & Config ) -> Option < Arc < Config > > {
502
- config. cdb . as_ref ( ) ?;
503
-
504
- Some ( Arc :: new ( Config { debugger : Some ( Debugger :: Cdb ) , ..config. clone ( ) } ) )
505
- }
506
-
507
- fn configure_gdb ( config : & Config ) -> Option < Arc < Config > > {
508
- config. gdb_version ?;
509
-
510
- if config. matches_env ( "msvc" ) {
511
- return None ;
512
- }
513
-
514
- if config. remote_test_client . is_some ( ) && !config. target . contains ( "android" ) {
515
- println ! (
516
- "WARNING: debuginfo tests are not available when \
517
- testing with remote"
518
- ) ;
519
- return None ;
520
- }
521
-
522
- if config. target . contains ( "android" ) {
523
- println ! (
524
- "{} debug-info test uses tcp 5039 port.\
525
- please reserve it",
526
- config. target
527
- ) ;
528
-
529
- // android debug-info test uses remote debugger so, we test 1 thread
530
- // at once as they're all sharing the same TCP port to communicate
531
- // over.
532
- //
533
- // we should figure out how to lift this restriction! (run them all
534
- // on different ports allocated dynamically).
535
- env:: set_var ( "RUST_TEST_THREADS" , "1" ) ;
536
- }
537
-
538
- Some ( Arc :: new ( Config { debugger : Some ( Debugger :: Gdb ) , ..config. clone ( ) } ) )
539
- }
540
-
541
- fn configure_lldb ( config : & Config ) -> Option < Arc < Config > > {
542
- config. lldb_python_dir . as_ref ( ) ?;
543
-
544
- if let Some ( 350 ) = config. lldb_version {
545
- println ! (
546
- "WARNING: The used version of LLDB (350) has a \
547
- known issue that breaks debuginfo tests. See \
548
- issue #32520 for more information. Skipping all \
549
- LLDB-based tests!",
550
- ) ;
551
- return None ;
552
- }
553
-
554
- Some ( Arc :: new ( Config { debugger : Some ( Debugger :: Lldb ) , ..config. clone ( ) } ) )
555
- }
556
-
557
504
pub fn test_opts ( config : & Config ) -> test:: TestOpts {
558
505
if env:: var ( "RUST_TEST_NOCAPTURE" ) . is_ok ( ) {
559
506
eprintln ! (
@@ -981,212 +928,6 @@ fn make_test_closure(
981
928
} ) )
982
929
}
983
930
984
- /// Returns `true` if the given target is an Android target for the
985
- /// purposes of GDB testing.
986
- fn is_android_gdb_target ( target : & str ) -> bool {
987
- matches ! (
988
- & target[ ..] ,
989
- "arm-linux-androideabi" | "armv7-linux-androideabi" | "aarch64-linux-android"
990
- )
991
- }
992
-
993
- /// Returns `true` if the given target is a MSVC target for the purposes of CDB testing.
994
- fn is_pc_windows_msvc_target ( target : & str ) -> bool {
995
- target. ends_with ( "-pc-windows-msvc" )
996
- }
997
-
998
- fn find_cdb ( target : & str ) -> Option < OsString > {
999
- if !( cfg ! ( windows) && is_pc_windows_msvc_target ( target) ) {
1000
- return None ;
1001
- }
1002
-
1003
- let pf86 = env:: var_os ( "ProgramFiles(x86)" ) . or_else ( || env:: var_os ( "ProgramFiles" ) ) ?;
1004
- let cdb_arch = if cfg ! ( target_arch = "x86" ) {
1005
- "x86"
1006
- } else if cfg ! ( target_arch = "x86_64" ) {
1007
- "x64"
1008
- } else if cfg ! ( target_arch = "aarch64" ) {
1009
- "arm64"
1010
- } else if cfg ! ( target_arch = "arm" ) {
1011
- "arm"
1012
- } else {
1013
- return None ; // No compatible CDB.exe in the Windows 10 SDK
1014
- } ;
1015
-
1016
- let mut path = PathBuf :: new ( ) ;
1017
- path. push ( pf86) ;
1018
- path. push ( r"Windows Kits\10\Debuggers" ) ; // We could check 8.1 etc. too?
1019
- path. push ( cdb_arch) ;
1020
- path. push ( r"cdb.exe" ) ;
1021
-
1022
- if !path. exists ( ) {
1023
- return None ;
1024
- }
1025
-
1026
- Some ( path. into_os_string ( ) )
1027
- }
1028
-
1029
- /// Returns Path to CDB
1030
- fn analyze_cdb ( cdb : Option < String > , target : & str ) -> ( Option < OsString > , Option < [ u16 ; 4 ] > ) {
1031
- let cdb = cdb. map ( OsString :: from) . or_else ( || find_cdb ( target) ) ;
1032
-
1033
- let mut version = None ;
1034
- if let Some ( cdb) = cdb. as_ref ( ) {
1035
- if let Ok ( output) = Command :: new ( cdb) . arg ( "/version" ) . output ( ) {
1036
- if let Some ( first_line) = String :: from_utf8_lossy ( & output. stdout ) . lines ( ) . next ( ) {
1037
- version = extract_cdb_version ( & first_line) ;
1038
- }
1039
- }
1040
- }
1041
-
1042
- ( cdb, version)
1043
- }
1044
-
1045
- fn extract_cdb_version ( full_version_line : & str ) -> Option < [ u16 ; 4 ] > {
1046
- // Example full_version_line: "cdb version 10.0.18362.1"
1047
- let version = full_version_line. rsplit ( ' ' ) . next ( ) ?;
1048
- let mut components = version. split ( '.' ) ;
1049
- let major: u16 = components. next ( ) . unwrap ( ) . parse ( ) . unwrap ( ) ;
1050
- let minor: u16 = components. next ( ) . unwrap ( ) . parse ( ) . unwrap ( ) ;
1051
- let patch: u16 = components. next ( ) . unwrap_or ( "0" ) . parse ( ) . unwrap ( ) ;
1052
- let build: u16 = components. next ( ) . unwrap_or ( "0" ) . parse ( ) . unwrap ( ) ;
1053
- Some ( [ major, minor, patch, build] )
1054
- }
1055
-
1056
- /// Returns (Path to GDB, GDB Version)
1057
- fn analyze_gdb (
1058
- gdb : Option < String > ,
1059
- target : & str ,
1060
- android_cross_path : & PathBuf ,
1061
- ) -> ( Option < String > , Option < u32 > ) {
1062
- #[ cfg( not( windows) ) ]
1063
- const GDB_FALLBACK : & str = "gdb" ;
1064
- #[ cfg( windows) ]
1065
- const GDB_FALLBACK : & str = "gdb.exe" ;
1066
-
1067
- let fallback_gdb = || {
1068
- if is_android_gdb_target ( target) {
1069
- let mut gdb_path = match android_cross_path. to_str ( ) {
1070
- Some ( x) => x. to_owned ( ) ,
1071
- None => panic ! ( "cannot find android cross path" ) ,
1072
- } ;
1073
- gdb_path. push_str ( "/bin/gdb" ) ;
1074
- gdb_path
1075
- } else {
1076
- GDB_FALLBACK . to_owned ( )
1077
- }
1078
- } ;
1079
-
1080
- let gdb = match gdb {
1081
- None => fallback_gdb ( ) ,
1082
- Some ( ref s) if s. is_empty ( ) => fallback_gdb ( ) , // may be empty if configure found no gdb
1083
- Some ( ref s) => s. to_owned ( ) ,
1084
- } ;
1085
-
1086
- let mut version_line = None ;
1087
- if let Ok ( output) = Command :: new ( & gdb) . arg ( "--version" ) . output ( ) {
1088
- if let Some ( first_line) = String :: from_utf8_lossy ( & output. stdout ) . lines ( ) . next ( ) {
1089
- version_line = Some ( first_line. to_string ( ) ) ;
1090
- }
1091
- }
1092
-
1093
- let version = match version_line {
1094
- Some ( line) => extract_gdb_version ( & line) ,
1095
- None => return ( None , None ) ,
1096
- } ;
1097
-
1098
- ( Some ( gdb) , version)
1099
- }
1100
-
1101
- fn extract_gdb_version ( full_version_line : & str ) -> Option < u32 > {
1102
- let full_version_line = full_version_line. trim ( ) ;
1103
-
1104
- // GDB versions look like this: "major.minor.patch?.yyyymmdd?", with both
1105
- // of the ? sections being optional
1106
-
1107
- // We will parse up to 3 digits for each component, ignoring the date
1108
-
1109
- // We skip text in parentheses. This avoids accidentally parsing
1110
- // the openSUSE version, which looks like:
1111
- // GNU gdb (GDB; openSUSE Leap 15.0) 8.1
1112
- // This particular form is documented in the GNU coding standards:
1113
- // https://www.gnu.org/prep/standards/html_node/_002d_002dversion.html#g_t_002d_002dversion
1114
-
1115
- let unbracketed_part = full_version_line. split ( '[' ) . next ( ) . unwrap ( ) ;
1116
- let mut splits = unbracketed_part. trim_end ( ) . rsplit ( ' ' ) ;
1117
- let version_string = splits. next ( ) . unwrap ( ) ;
1118
-
1119
- let mut splits = version_string. split ( '.' ) ;
1120
- let major = splits. next ( ) . unwrap ( ) ;
1121
- let minor = splits. next ( ) . unwrap ( ) ;
1122
- let patch = splits. next ( ) ;
1123
-
1124
- let major: u32 = major. parse ( ) . unwrap ( ) ;
1125
- let ( minor, patch) : ( u32 , u32 ) = match minor. find ( not_a_digit) {
1126
- None => {
1127
- let minor = minor. parse ( ) . unwrap ( ) ;
1128
- let patch: u32 = match patch {
1129
- Some ( patch) => match patch. find ( not_a_digit) {
1130
- None => patch. parse ( ) . unwrap ( ) ,
1131
- Some ( idx) if idx > 3 => 0 ,
1132
- Some ( idx) => patch[ ..idx] . parse ( ) . unwrap ( ) ,
1133
- } ,
1134
- None => 0 ,
1135
- } ;
1136
- ( minor, patch)
1137
- }
1138
- // There is no patch version after minor-date (e.g. "4-2012").
1139
- Some ( idx) => {
1140
- let minor = minor[ ..idx] . parse ( ) . unwrap ( ) ;
1141
- ( minor, 0 )
1142
- }
1143
- } ;
1144
-
1145
- Some ( ( ( major * 1000 ) + minor) * 1000 + patch)
1146
- }
1147
-
1148
- /// Returns LLDB version
1149
- fn extract_lldb_version ( full_version_line : & str ) -> Option < u32 > {
1150
- // Extract the major LLDB version from the given version string.
1151
- // LLDB version strings are different for Apple and non-Apple platforms.
1152
- // The Apple variant looks like this:
1153
- //
1154
- // LLDB-179.5 (older versions)
1155
- // lldb-300.2.51 (new versions)
1156
- //
1157
- // We are only interested in the major version number, so this function
1158
- // will return `Some(179)` and `Some(300)` respectively.
1159
- //
1160
- // Upstream versions look like:
1161
- // lldb version 6.0.1
1162
- //
1163
- // There doesn't seem to be a way to correlate the Apple version
1164
- // with the upstream version, and since the tests were originally
1165
- // written against Apple versions, we make a fake Apple version by
1166
- // multiplying the first number by 100. This is a hack.
1167
-
1168
- let full_version_line = full_version_line. trim ( ) ;
1169
-
1170
- if let Some ( apple_ver) =
1171
- full_version_line. strip_prefix ( "LLDB-" ) . or_else ( || full_version_line. strip_prefix ( "lldb-" ) )
1172
- {
1173
- if let Some ( idx) = apple_ver. find ( not_a_digit) {
1174
- let version: u32 = apple_ver[ ..idx] . parse ( ) . unwrap ( ) ;
1175
- return Some ( version) ;
1176
- }
1177
- } else if let Some ( lldb_ver) = full_version_line. strip_prefix ( "lldb version " ) {
1178
- if let Some ( idx) = lldb_ver. find ( not_a_digit) {
1179
- let version: u32 = lldb_ver[ ..idx] . parse ( ) . ok ( ) ?;
1180
- return Some ( version * 100 ) ;
1181
- }
1182
- }
1183
- None
1184
- }
1185
-
1186
- fn not_a_digit ( c : char ) -> bool {
1187
- !c. is_ascii_digit ( )
1188
- }
1189
-
1190
931
fn check_overlapping_tests ( found_paths : & HashSet < PathBuf > ) {
1191
932
let mut collisions = Vec :: new ( ) ;
1192
933
for path in found_paths {
0 commit comments