forked from OSchip/llvm-project
Fix a bug caused by my alias refactoring where, if an alias was defined in terms of another alias, trying to run the nested command would actually cause a crash in the command interpreter
llvm-svn: 264096
This commit is contained in:
parent
00294b34a3
commit
660764a060
|
@ -93,9 +93,16 @@ public:
|
|||
|
||||
lldb::CommandObjectSP GetUnderlyingCommand() { return m_underlying_command_sp; }
|
||||
OptionArgVectorSP GetOptionArguments() { return m_option_args_sp; }
|
||||
const char* GetOptionString() { return m_option_string.c_str(); }
|
||||
|
||||
// this takes an alias - potentially nested (i.e. an alias to an alias)
|
||||
// and expands it all the way to a non-alias command
|
||||
std::pair<lldb::CommandObjectSP, OptionArgVectorSP>
|
||||
Desugar ();
|
||||
|
||||
private:
|
||||
lldb::CommandObjectSP m_underlying_command_sp;
|
||||
std::string m_option_string;
|
||||
OptionArgVectorSP m_option_args_sp ;
|
||||
LazyBool m_is_dashdash_alias;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../make
|
||||
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -0,0 +1,60 @@
|
|||
"""
|
||||
Test that an alias can reference other aliases without crashing.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
|
||||
|
||||
import os, time
|
||||
import re
|
||||
import lldb
|
||||
from lldbsuite.test.lldbtest import *
|
||||
import lldbsuite.test.lldbutil as lldbutil
|
||||
|
||||
class NestedAliasTestCase(TestBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
TestBase.setUp(self)
|
||||
# Find the line number to break inside main().
|
||||
self.line = line_number('main.cpp', '// break here')
|
||||
|
||||
def test_nested_alias(self):
|
||||
"""Test that an alias can reference other aliases without crashing."""
|
||||
self.build()
|
||||
exe = os.path.join(os.getcwd(), "a.out")
|
||||
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
|
||||
|
||||
# Break in main() aftre the variables are assigned values.
|
||||
lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
|
||||
|
||||
self.runCmd("run", RUN_SUCCEEDED)
|
||||
|
||||
# The stop reason of the thread should be breakpoint.
|
||||
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
|
||||
substrs = ['stopped', 'stop reason = breakpoint'])
|
||||
|
||||
# The breakpoint should have a hit count of 1.
|
||||
self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
|
||||
substrs = [' resolved, hit count = 1'])
|
||||
|
||||
# This is the function to remove the custom aliases in order to have a
|
||||
# clean slate for the next test case.
|
||||
def cleanup():
|
||||
self.runCmd('command unalias read', check=False)
|
||||
self.runCmd('command unalias rd', check=False)
|
||||
|
||||
# Execute the cleanup function during test case tear down.
|
||||
self.addTearDownHook(cleanup)
|
||||
|
||||
self.runCmd('command alias read memory read -f A')
|
||||
self.runCmd('command alias rd read -c 3')
|
||||
|
||||
self.expect('memory read -f A -c 3 `&my_ptr[0]`', substrs=['deadbeef', 'main.cpp:', 'feedbeef'])
|
||||
self.expect('rd `&my_ptr[0]`', substrs=['deadbeef', 'main.cpp:', 'feedbeef'])
|
||||
|
||||
self.expect('memory read -f A -c 3 `&my_ptr[0]`', substrs=['deadfeed'], matching=False)
|
||||
self.expect('rd `&my_ptr[0]`', substrs=['deadfeed'], matching=False)
|
|
@ -0,0 +1,22 @@
|
|||
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include <stdio.h>
|
||||
|
||||
int main (int argc, char const *argv[])
|
||||
{
|
||||
void* my_ptr[] = {
|
||||
reinterpret_cast<void*>(0xDEADBEEF),
|
||||
reinterpret_cast<void*>(main),
|
||||
reinterpret_cast<void*>(0xFEEDBEEF),
|
||||
reinterpret_cast<void*>(0xFEEDDEAD),
|
||||
reinterpret_cast<void*>(0xDEADFEED)
|
||||
};
|
||||
return 0; // break here
|
||||
}
|
||||
|
|
@ -85,6 +85,7 @@ CommandAlias::CommandAlias (CommandInterpreter &interpreter,
|
|||
syntax,
|
||||
flags),
|
||||
m_underlying_command_sp(),
|
||||
m_option_string(options_args ? options_args : ""),
|
||||
m_option_args_sp(new OptionArgVector),
|
||||
m_is_dashdash_alias(eLazyBoolCalculate)
|
||||
{
|
||||
|
@ -238,6 +239,24 @@ CommandAlias::IsDashDashCommand ()
|
|||
return (m_is_dashdash_alias == eLazyBoolYes);
|
||||
}
|
||||
|
||||
std::pair<lldb::CommandObjectSP, OptionArgVectorSP>
|
||||
CommandAlias::Desugar ()
|
||||
{
|
||||
auto underlying = GetUnderlyingCommand();
|
||||
if (!underlying)
|
||||
return {nullptr,nullptr};
|
||||
|
||||
if (underlying->IsAlias())
|
||||
{
|
||||
auto desugared = ((CommandAlias*)underlying.get())->Desugar();
|
||||
auto options = GetOptionArguments();
|
||||
options->insert(options->begin(), desugared.second->begin(), desugared.second->end());
|
||||
return {desugared.first,options};
|
||||
}
|
||||
|
||||
return {underlying,GetOptionArguments()};
|
||||
}
|
||||
|
||||
// allow CommandAlias objects to provide their own help, but fallback to the info
|
||||
// for the underlying command if no customization has been provided
|
||||
const char*
|
||||
|
|
|
@ -1359,8 +1359,9 @@ CommandInterpreter::BuildAliasResult (const char *alias_name,
|
|||
|
||||
if (alias_cmd_obj && alias_cmd_obj->IsAlias())
|
||||
{
|
||||
OptionArgVectorSP option_arg_vector_sp = ((CommandAlias*)alias_cmd_obj)->GetOptionArguments();
|
||||
alias_cmd_obj = ((CommandAlias*)alias_cmd_obj)->GetUnderlyingCommand().get();
|
||||
std::pair<CommandObjectSP, OptionArgVectorSP> desugared = ((CommandAlias*)alias_cmd_obj)->Desugar();
|
||||
OptionArgVectorSP option_arg_vector_sp = desugared.second;
|
||||
alias_cmd_obj = desugared.first.get();
|
||||
std::string alias_name_str = alias_name;
|
||||
if ((cmd_args.GetArgumentCount() == 0)
|
||||
|| (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0))
|
||||
|
|
Loading…
Reference in New Issue