Skip to content

Commit

Permalink
Create prettier messages when fcd crashes
Browse files Browse the repository at this point in the history
This commit prints a program stack trace and a 'logical stack trace' (built from annotation objects sprinkled in important source locations) on abnormal termination.
  • Loading branch information
fay59 committed Apr 2, 2017
1 parent 74194c8 commit 20e121a
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 0 deletions.
4 changes: 4 additions & 0 deletions fcd/ast/pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#include "pass.h"

#include <llvm/Support/PrettyStackTrace.h>

using namespace llvm;
using namespace std;

Expand Down Expand Up @@ -51,6 +53,8 @@ void AstFunctionPass::doRun(deque<unique_ptr<FunctionNode>>& list)
{
if (runOnDeclarations || fn->hasBody())
{
PrettyStackTraceFormat runPass("Running AST pass \"%s\" on function \"%s\"", getName(), string(fn->getFunction().getName()).c_str());

this->fn = fn.get();
doRun(*fn);
}
Expand Down
21 changes: 21 additions & 0 deletions fcd/callconv/params_registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <llvm/Analysis/TargetLibraryInfo.h>
#include <llvm/IR/Dominators.h>
#include <llvm/IR/Module.h>
#include <llvm/Support/PrettyStackTrace.h>

using namespace llvm;
using namespace std;
Expand Down Expand Up @@ -193,6 +194,8 @@ CallInformation* ParameterRegistry::analyzeFunction(Function& fn)
{
for (CallingConvention* cc : ccChain)
{
PrettyStackTraceFormat analyzing("Analyzing function \"%s\" with calling convention \"%s\"", string(fn.getName()).c_str(), cc->getName());

info.setStage(CallInformation::Analyzing);
if (cc->analyzeFunction(*this, info, fn))
{
Expand Down Expand Up @@ -273,6 +276,12 @@ const CallInformation* ParameterRegistry::getDefinitionCallInfo(Function& functi
{
for (CallingConvention* cc : *this)
{
string functionType;
raw_string_ostream functionTypeStream(functionType);
function.getFunctionType()->print(functionTypeStream);
functionTypeStream.flush();
PrettyStackTraceFormat analyzing("Analyzing function type \"%s\" with calling convention \"%s\"", functionType.c_str(), cc->getName());

if (cc->analyzeFunctionType(*this, info, *function.getFunctionType()))
{
info.setCallingConvention(cc);
Expand All @@ -293,6 +302,18 @@ unique_ptr<CallInformation> ParameterRegistry::analyzeCallSite(CallSite callSite
unique_ptr<CallInformation> info(new CallInformation);
for (CallingConvention* cc : ccChain)
{
string calleeName;
if (auto callee = callSite.getCalledFunction())
{
calleeName = callee->getName();
}
else
{
calleeName = "(not a function)";
}
string callerName = callSite->getFunction()->getName();
PrettyStackTraceFormat analyzing("Analyzing call site for \"%s\" in \"%s\" with calling convention \"%s\"", calleeName.c_str(), callerName.c_str(), cc->getName());

info->setStage(CallInformation::Analyzing);
if (cc->analyzeCallSite(*this, *info, callSite))
{
Expand Down
3 changes: 3 additions & 0 deletions fcd/codegen/translation_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <llvm/ADT/Triple.h>
#include <llvm/IR/IntrinsicInst.h>
#include <llvm/IR/Verifier.h>
#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/raw_os_ostream.h>
#include <llvm/Transforms/Scalar.h>
#include <llvm/Transforms/Utils/Cloning.h>
Expand Down Expand Up @@ -252,6 +253,8 @@ void TranslationContext::setFunctionName(uint64_t address, const std::string &na

Function* TranslationContext::createFunction(uint64_t baseAddress)
{
PrettyStackTraceFormat creatingFunction("Creating function for code address 0x%" PRIx64, baseAddress);

Function* fn = functionMap->createFunction(baseAddress);
assert(fn != nullptr);

Expand Down
3 changes: 3 additions & 0 deletions fcd/executables/elf_executable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "elf_executable.h"
#include "executable_errors.h"

#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/raw_ostream.h>

#include <array>
Expand Down Expand Up @@ -911,6 +912,8 @@ ElfExecutableFactory::ElfExecutableFactory()

ErrorOr<unique_ptr<Executable>> ElfExecutableFactory::parse(const uint8_t* begin, const uint8_t* end)
{
PrettyStackTraceString frameInfo("Parsing executable as ELF executable");

if (auto endianByte = bounded_cast<uint8_t>(begin, end, EI_DATA))
{
// We currently don't support non-native endianness (yet). At least return null if the ELF's endianness does not
Expand Down
3 changes: 3 additions & 0 deletions fcd/executables/flat_binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "executable_errors.h"
#include "flat_binary.h"

#include <llvm/Support/PrettyStackTrace.h>

using namespace llvm;
using namespace std;

Expand Down Expand Up @@ -64,6 +66,7 @@ FlatBinaryExecutableFactory::FlatBinaryExecutableFactory()

ErrorOr<unique_ptr<Executable>> FlatBinaryExecutableFactory::parse(const uint8_t* begin, const uint8_t* end)
{
PrettyStackTraceString frameInfo("Parsing executable as flat binary");
auto executable = std::make_unique<FlatBinary>(begin, end, flatOrigin);
return move(executable);
}
2 changes: 2 additions & 0 deletions fcd/executables/python_executable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "python_executable.h"
#include "python_helpers.h"

#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/raw_ostream.h>

#include <unordered_map>
Expand Down Expand Up @@ -344,5 +345,6 @@ PythonExecutableFactory::PythonExecutableFactory()

ErrorOr<unique_ptr<Executable>> PythonExecutableFactory::parse(const uint8_t* begin, const uint8_t* end)
{
PrettyStackTraceFormat parsing("Parsing executable with Python script \"%s\"", scriptPath.c_str());
return PythonParsedExecutable::create(scriptPath, begin, end);
}
3 changes: 3 additions & 0 deletions fcd/header_decls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <llvm/IR/CallingConv.h>
#include <llvm/IR/Function.h>
#include <llvm/Support/Path.h>
#include <llvm/Support/PrettyStackTrace.h>

#include <dlfcn.h>

Expand Down Expand Up @@ -167,6 +168,8 @@ unique_ptr<HeaderDeclarations> HeaderDeclarations::create(llvm::Module& module,
return unique_ptr<HeaderDeclarations>(new HeaderDeclarations(module, nullptr, move(headers)));
}

PrettyStackTraceString parsingHeaders("Parsing header files");

string includeContent;
raw_string_ostream includer(includeContent);
includer << "#define FCD_ADDRESS(x) __attribute__((annotate(\"fcd.virtualaddress:\" #x)))\n";
Expand Down
13 changes: 13 additions & 0 deletions fcd/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@
#include <llvm/Support/FileSystem.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/Path.h>
#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/Process.h>
#include <llvm/Support/raw_os_ostream.h>
#include <llvm/Support/Signals.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Transforms/IPO.h>
#include <llvm/Transforms/Scalar.h>
Expand Down Expand Up @@ -513,6 +515,8 @@ namespace

bool optimizeAndTransformModule(Module& module, raw_ostream& errorOutput, Executable* executable = nullptr)
{
PrettyStackTraceString optimize("Optimizing LLVM IR");

// Phase 3: make into functions with arguments, run codegen.
auto passManager = createBasePassManager();
passManager.add(new ExecutableWrapper(executable));
Expand All @@ -536,6 +540,8 @@ namespace

bool generateEquivalentPseudocode(Module& module, raw_ostream& output)
{
PrettyStackTraceString pseudocode("Generating pseudo-C output");

// Run that module through the output pass
// UnwrapReturns happens after value propagation because value propagation doesn't know that calls
// are generally not safe to reorder.
Expand Down Expand Up @@ -658,6 +664,9 @@ bool isEntryPoint(uint64_t vaddr)

int main(int argc, char** argv)
{
EnablePrettyStackTrace();
sys::PrintStackTraceOnErrorSignal(argv[0]);

pruneOptionList(cl::getRegisteredOptions());
cl::ParseCommandLineOptions(argc, argv, "native program decompiler");

Expand Down Expand Up @@ -687,6 +696,8 @@ int main(int argc, char** argv)
ErrorOr<unique_ptr<MemoryBuffer>> bufferOrError(nullptr);
if (moduleInCount())
{
PrettyStackTraceFormat parsingIR("Parsing IR from \"%s\"", inputFile.c_str());

SMDiagnostic errors;
module = parseIRFile(inputFile, errors, mainObj.getContext());
if (!module)
Expand All @@ -697,6 +708,8 @@ int main(int argc, char** argv)
}
else
{
PrettyStackTraceFormat parsingIR("Parsing executable \"%s\"", inputFile.c_str());

bufferOrError = MemoryBuffer::getFile(inputFile, -1, false);
if (!bufferOrError)
{
Expand Down

0 comments on commit 20e121a

Please sign in to comment.