Commit 187b3dfa by Karl Schimpf

Fix locking for printing error messages.

The method TopLevelParser::ErrorAt applies a lock to print the error message. Unfortunately, it keeps the lock longer than necessary, resulting in deadlock (on following fatal message) if error recovery is not allowed. Fixed by limiting scope of lock to only apply to the printing of the error message. Modified ClFlags to allow a "reset", and made ClFlags modifiable by bitcode munge tests. This allowed us to test this problem as a unit test. BUG= https://code.google.com/p/nativeclient/issues/detail?id=4138 R=jvoung@chromium.org Review URL: https://codereview.chromium.org/1091023002
parent d8fb3d33
......@@ -245,6 +245,43 @@ void ClFlags::parseFlags(int argc, char **argv) {
AppName = IceString(argv[0]);
}
void ClFlags::resetClFlags(ClFlags &OutFlags) {
// bool fields
OutFlags.AllowErrorRecovery = false;
OutFlags.AllowUninitializedGlobals = false;
OutFlags.DataSections = false;
OutFlags.DecorateAsm = false;
OutFlags.DisableInternal = false;
OutFlags.DisableIRGeneration = false;
OutFlags.DisableTranslation = false;
OutFlags.DumpStats = false;
OutFlags.FunctionSections = false;
OutFlags.GenerateUnitTestMessages = false;
OutFlags.PhiEdgeSplit = false;
OutFlags.RandomNopInsertion = false;
OutFlags.RandomRegAlloc = false;
OutFlags.SubzeroTimingEnabled = false;
OutFlags.TimeEachFunction = false;
OutFlags.UseSandboxing = false;
// Enum and integer fields.
OutFlags.Opt = Opt_m1;
OutFlags.OutFileType = FT_Iasm;
OutFlags.RandomMaxNopsPerInstruction = 0;
OutFlags.RandomNopProbabilityAsPercentage = 0;
OutFlags.TArch = TargetArch_NUM;
OutFlags.VMask = IceV_None;
// IceString fields.
OutFlags.DefaultFunctionPrefix = "";
OutFlags.DefaultGlobalPrefix = "";
OutFlags.TestPrefix = "";
OutFlags.TimingFocusOn = "";
OutFlags.TranslateOnly = "";
OutFlags.VerboseFocusOn = "";
// size_t and 64-bit fields.
OutFlags.NumTranslationThreads = 0;
OutFlags.RandomSeed = 0;
}
void ClFlags::getParsedClFlags(ClFlags &OutFlags) {
if (::DisableIRGeneration)
::DisableTranslation = true;
......
......@@ -26,27 +26,10 @@ class ClFlags {
ClFlags &operator=(const ClFlags &) = delete;
public:
ClFlags()
: // bool fields.
AllowErrorRecovery(false),
AllowUninitializedGlobals(false), DataSections(false),
DecorateAsm(false), DisableInternal(false), DisableIRGeneration(false),
DisableTranslation(false), DumpStats(false), FunctionSections(false),
GenerateUnitTestMessages(false), PhiEdgeSplit(false),
RandomNopInsertion(false), RandomRegAlloc(false),
SubzeroTimingEnabled(false), TimeEachFunction(false),
UseSandboxing(false),
// Enum and integer fields.
Opt(Opt_m1), OutFileType(FT_Iasm), RandomMaxNopsPerInstruction(0),
RandomNopProbabilityAsPercentage(0), TArch(TargetArch_NUM),
VMask(IceV_None),
// IceString fields.
DefaultFunctionPrefix(""), DefaultGlobalPrefix(""), TestPrefix(""),
TimingFocusOn(""), TranslateOnly(""), VerboseFocusOn(""),
// size_t and 64-bit fields.
NumTranslationThreads(0), RandomSeed(0) {}
ClFlags() { resetClFlags(*this); }
static void parseFlags(int argc, char *argv[]);
static void resetClFlags(ClFlags &OutFlags);
static void getParsedClFlags(ClFlags &OutFlags);
static void getParsedClFlagsExtra(ClFlagsExtra &OutFlagsExtra);
......
......@@ -486,10 +486,12 @@ bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
ErrorStatus.assign(Ice::EC_Bitcode);
++NumErrors;
Ice::GlobalContext *Context = Translator.getContext();
{ // Lock while printing out error message.
Ice::OstreamLocker L(Context);
raw_ostream &OldErrStream = setErrStream(Context->getStrDump());
NaClBitcodeParser::ErrorAt(Level, Bit, Message);
setErrStream(OldErrStream);
}
if (Level >= naclbitc::Error &&
!Translator.getFlags().getAllowErrorRecovery())
Fatal();
......
......@@ -19,19 +19,25 @@
namespace IceTest {
bool IceTest::SubzeroBitcodeMunger::runTest(const char *TestName,
const uint64_t Munges[],
size_t MungeSize) {
const bool AddHeader = true;
setupTest(TestName, Munges, MungeSize, AddHeader);
void IceTest::SubzeroBitcodeMunger::resetFlags() {
Ice::ClFlags::resetClFlags(Flags);
resetMungeFlags();
}
Ice::ClFlags Flags;
void IceTest::SubzeroBitcodeMunger::resetMungeFlags() {
Flags.setAllowErrorRecovery(true);
Flags.setGenerateUnitTestMessages(true);
Flags.setOptLevel(Ice::Opt_m1);
Flags.setOutFileType(Ice::FT_Iasm);
Flags.setTargetArch(Ice::Target_X8632);
Flags.setVerbose(Ice::IceV_Instructions);
}
bool IceTest::SubzeroBitcodeMunger::runTest(const char *TestName,
const uint64_t Munges[],
size_t MungeSize) {
const bool AddHeader = true;
setupTest(TestName, Munges, MungeSize, AddHeader);
Ice::GlobalContext Ctx(DumpStream, DumpStream, nullptr, Flags);
Ice::PNaClTranslator Translator(&Ctx);
Translator.translateBuffer(TestName, MungedInput.get());
......
......@@ -17,6 +17,8 @@
#include "llvm/Bitcode/NaCl/NaClBitcodeMunge.h"
#include "IceClFlags.h"
namespace IceTest {
// Class to run tests on Subzero's bitcode parser. Runs a Subzero
......@@ -27,7 +29,9 @@ class SubzeroBitcodeMunger : public llvm::NaClBitcodeMunger {
public:
SubzeroBitcodeMunger(const uint64_t Records[], size_t RecordSize,
uint64_t RecordTerminator)
: llvm::NaClBitcodeMunger(Records, RecordSize, RecordTerminator) {}
: llvm::NaClBitcodeMunger(Records, RecordSize, RecordTerminator) {
resetMungeFlags();
}
/// Runs PNaClTranslator to translate bitcode records (with defined
/// record Munges), and puts output into DumpResults. Returns true
......@@ -39,6 +43,15 @@ public:
uint64_t NoMunges[] = {0};
return runTest(TestName, NoMunges, 0);
}
/// Sets flags back to default assumptions for munging.
void resetFlags();
/// Flags to use to run tests. Use to change default assumptions.
Ice::ClFlags Flags;
private:
void resetMungeFlags();
};
} // end of namespace IceTest
......
......@@ -63,6 +63,12 @@ TEST(IceParseInstsTest, NonexistentCallArg) {
EXPECT_FALSE(Munger.runTest("Nonexistent call arg"));
EXPECT_EQ("Error(66:4): Invalid function record: <34 0 4 2 100>\n",
Munger.getTestResults());
// Show that we generate a fatal error when not allowing error recovery.
Munger.Flags.setAllowErrorRecovery(false);
EXPECT_DEATH(
Munger.runTest("Nonexistent call arg"),
".*ERROR: Unable to continue.*");
}
/// Test how we recognize alignments in alloca instructions.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment