Index: packages/Python/lldbsuite/test/functionalities/target_command/TestTargetCommand.py =================================================================== --- packages/Python/lldbsuite/test/functionalities/target_command/TestTargetCommand.py +++ packages/Python/lldbsuite/test/functionalities/target_command/TestTargetCommand.py @@ -59,6 +59,24 @@ self.do_target_variable_command_no_fail('globals') + @expectedFailureAndroid(archs=['aarch64']) + def test_target_variable_after_print_command(self): + """Test 'print' command before and 'target var' after starting the inferior.""" + d = {'C_SOURCES': 'globals.c', 'EXE': 'globals'} + self.build(dictionary=d) + self.addTearDownCleanup(dictionary=d) + + self.do_target_variable_after_print_command('globals') + + @expectedFailureAndroid(archs=['aarch64']) + def test_target_variable_with_regex(self): + """Test 'target var -r' command before and 'target var' after starting the inferior.""" + d = {'C_SOURCES': 'globals.c', 'EXE': 'globals'} + self.build(dictionary=d) + self.addTearDownCleanup(dictionary=d) + + self.do_target_variable_with_regex('globals') + def do_target_command(self): """Exercise 'target create', 'target list', 'target select' commands.""" exe_a = os.path.join(os.getcwd(), "a.out") @@ -245,7 +263,8 @@ substrs=['my_global_char', 'my_global_str', 'my_global_str_ptr', - 'my_static_int']) + 'my_static_int', + 'my_global_int']) self.expect( "target variable my_global_str", @@ -273,3 +292,49 @@ substrs=[ "my_global_char", "'X'"]) + + def do_target_variable_after_print_command(self, exe_name): + """Exercise 'print' command before and 'target var' after starting the inferior.""" + self.runCmd("file " + exe_name, CURRENT_EXECUTABLE_SET) + + self.expect( + "target variable my_global_char", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "my_global_char", + "'X'"]) + + self.runCmd("b main") + self.runCmd("run") + + # To test whether all varaible are shown if we print only one variable before + # starting inferior + self.expect("target variable", + substrs=['my_global_char', + 'my_global_str', + 'my_global_str_ptr', + 'my_static_int', + 'my_global_int']) + + def do_target_variable_with_regex(self, exe_name): + """Exercise 'target var -r' command before and 'target var' after starting the inferior.""" + self.runCmd("file " + exe_name, CURRENT_EXECUTABLE_SET) + + self.expect( + "target variable -r my_global_ch*", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "my_global_char", + "'X'"]) + + self.runCmd("b main") + self.runCmd("run") + + # To test whether all varaible are shown if we use regex for one variable before + # starting inferior + self.expect("target variable", + substrs=['my_global_char', + 'my_global_str', + 'my_global_str_ptr', + 'my_static_int', + 'my_global_int']) Index: packages/Python/lldbsuite/test/functionalities/target_command/globals.c =================================================================== --- packages/Python/lldbsuite/test/functionalities/target_command/globals.c +++ packages/Python/lldbsuite/test/functionalities/target_command/globals.c @@ -12,6 +12,7 @@ const char* my_global_str = "abc"; const char **my_global_str_ptr = &my_global_str; static int my_static_int = 228; +int my_global_int = 10; int main (int argc, char const *argv[]) { Index: source/Commands/CommandObjectTarget.cpp =================================================================== --- source/Commands/CommandObjectTarget.cpp +++ source/Commands/CommandObjectTarget.cpp @@ -836,9 +836,25 @@ return false; } use_var_name = true; + if (!m_exe_ctx.GetFramePtr()) { + VariableList list; + lldb_private::RegularExpression all_globals_regex("."); + target->GetImages().FindGlobalVariables(all_globals_regex, true, + UINT32_MAX, list); + } matches = target->GetImages().FindGlobalVariables( regex, true, UINT32_MAX, variable_list); } else { + // if there is no frame then it is before "r" ing the exe, so just + // parse all the variables + // before picking proper otherwise we end up adding only this variable + // in m_variables + if (!m_exe_ctx.GetFramePtr()) { + VariableList list; + lldb_private::RegularExpression all_globals_regex("."); + target->GetImages().FindGlobalVariables(all_globals_regex, true, + UINT32_MAX, list); + } Error error(Variable::GetValuesForVariableExpressionPath( arg, m_exe_ctx.GetBestExecutionContextScope(), GetVariableCallback, target, variable_list, valobj_list)); Index: source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h +++ source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h @@ -303,6 +303,23 @@ TargetInfo GetTargetInfo(); //------------------------------------------------------------------ + /// Used to parse all the variable declared in globa score before accssing + /// indivually when user try to see the global symbol before starting + /// execution. + /// + /// @param[in] target + /// The target to find the symbol in. + /// + /// @param[in] name + /// Symbol name that user try to print. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ + + void ParseGlobalVariablesInScopeZero(Target &target, const ConstString name); + + //------------------------------------------------------------------ /// [Used by ClangASTSource] Find all entities matching a given name, /// using a NameSearchContext to make Decls for them. /// Index: source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -733,6 +733,28 @@ frame_decl_context.GetTypeSystem()); } +void ClangExpressionDeclMap::ParseGlobalVariablesInScopeZero( + Target &target, const ConstString name) { + const Symbol *symbol = FindGlobalDataSymbol(target, name, NULL); + ModuleSP module; + + if (!symbol) + return; + + if (symbol->ValueIsAddress()) + module = symbol->GetAddressRef().GetModule(); + + SymbolVendor *vendor_sym = module->GetSymbolVendor(true, NULL); + SymbolContext sc; + + sc.module_sp = module; + sc.comp_unit = symbol->GetAddress().CalculateSymbolContextCompileUnit(); + + vendor_sym->ParseVariablesForContext(sc); + + return; +} + // Interface for ClangASTSource void ClangExpressionDeclMap::FindExternalVisibleDecls( @@ -1229,6 +1251,11 @@ } } if (target) { + // Looks like trying to find a variable before program is run. + // So parse the global variable for declaration. + + ParseGlobalVariablesInScopeZero(*target, name); + var = FindGlobalVariable(*target, module_sp, name, &namespace_decl, NULL); if (var) {