Add debug listener

pull/6/head
A. R. Shajii 2021-11-13 11:22:11 -05:00
parent 9e1aa03bd5
commit fb04f81d3f
7 changed files with 110 additions and 15 deletions

View File

@ -83,9 +83,11 @@ add_definitions(${LLVM_DEFINITIONS})
set(CODON_HPPFILES
codon/compiler/compiler.h
codon/compiler/debug_listener.h
codon/compiler/engine.h
codon/compiler/error.h
codon/compiler/jit.h
codon/compiler/memory_manager.h
codon/dsl/dsl.h
codon/dsl/plugins.h
codon/parser/ast.h
@ -129,7 +131,6 @@ set(CODON_HPPFILES
codon/sir/llvm/coro/Coroutines.h
codon/sir/llvm/llvisitor.h
codon/sir/llvm/llvm.h
codon/sir/llvm/memory_manager.h
codon/sir/llvm/optimize.h
codon/sir/module.h
codon/sir/sir.h
@ -209,9 +210,11 @@ set(CODON_HPPFILES
extra/jupyter/src/codon.h)
set(CODON_CPPFILES
codon/compiler/compiler.cpp
codon/compiler/debug_listener.cpp
codon/compiler/engine.cpp
codon/compiler/error.cpp
codon/compiler/jit.cpp
codon/compiler/memory_manager.cpp
codon/dsl/plugins.cpp
codon/parser/ast/expr.cpp
codon/parser/ast/stmt.cpp
@ -253,7 +256,6 @@ set(CODON_CPPFILES
codon/sir/llvm/coro/CoroSplit.cpp
codon/sir/llvm/coro/Coroutines.cpp
codon/sir/llvm/llvisitor.cpp
codon/sir/llvm/memory_manager.cpp
codon/sir/llvm/optimize.cpp
codon/sir/module.cpp
codon/sir/transform/cleanup/canonical.cpp

View File

@ -0,0 +1,50 @@
#include "debug_listener.h"
#include <algorithm>
#include <iostream>
namespace codon {
void DebugListener::notifyObjectLoaded(ObjectKey key,
const llvm::object::ObjectFile &obj,
const llvm::RuntimeDyld::LoadedObjectInfo &L) {
intptr_t start = 0, stop = 0;
for (const auto &sec : obj.sections()) {
if (sec.isText()) {
start = L.getSectionLoadAddress(sec);
stop = start + sec.getSize();
break;
}
}
auto saved = L.getObjectForDebug(obj).takeBinary();
if (!saved.first) {
auto buf = llvm::MemoryBuffer::getMemBufferCopy(obj.getData(), obj.getFileName());
auto newObj = llvm::cantFail(
llvm::object::ObjectFile::createObjectFile(buf->getMemBufferRef()));
saved = std::make_pair(std::move(newObj), std::move(buf));
}
objects.emplace_back(key, std::move(saved.first), std::move(saved.second), start,
stop);
}
void DebugListener::notifyFreeingObject(ObjectKey key) {
objects.erase(
std::remove_if(objects.begin(), objects.end(),
[key](const ObjectInfo &o) { return key == o.getKey(); }),
objects.end());
}
llvm::Expected<llvm::DILineInfo> DebugListener::symbolize(intptr_t pc) const {
for (const auto &o : objects) {
if (o.contains(pc)) {
llvm::symbolize::LLVMSymbolizer sym;
return sym.symbolizeCode(o.getObject(),
{static_cast<uint64_t>(pc - o.getStart()),
llvm::object::SectionedAddress::UndefSection});
}
}
return llvm::DILineInfo();
}
} // namespace codon

View File

@ -0,0 +1,49 @@
#pragma once
#include <memory>
#include <utility>
#include <vector>
#include "codon/sir/llvm/llvm.h"
namespace codon {
class DebugListener : public llvm::JITEventListener {
public:
class ObjectInfo {
private:
ObjectKey key;
std::unique_ptr<llvm::object::ObjectFile> object;
std::unique_ptr<llvm::MemoryBuffer> buffer;
intptr_t start;
intptr_t stop;
public:
ObjectInfo(ObjectKey key, std::unique_ptr<llvm::object::ObjectFile> object,
std::unique_ptr<llvm::MemoryBuffer> buffer, intptr_t start,
intptr_t stop)
: key(key), object(std::move(object)), buffer(std::move(buffer)), start(start),
stop(stop) {}
ObjectKey getKey() const { return key; }
const llvm::object::ObjectFile &getObject() const { return *object; }
const llvm::MemoryBuffer &getBuffer() const { return *buffer; }
intptr_t getStart() const { return start; }
intptr_t getStop() const { return stop; }
bool contains(intptr_t pc) const { return start <= pc && pc < stop; }
};
private:
std::vector<ObjectInfo> objects;
void notifyObjectLoaded(ObjectKey key, const llvm::object::ObjectFile &obj,
const llvm::RuntimeDyld::LoadedObjectInfo &L) override;
void notifyFreeingObject(ObjectKey key) override;
public:
DebugListener() : llvm::JITEventListener(), objects() {}
llvm::Expected<llvm::DILineInfo> symbolize(intptr_t pc) const;
};
} // namespace codon

View File

@ -1,6 +1,6 @@
#include "engine.h"
#include "codon/sir/llvm/memory_manager.h"
#include "codon/compiler/memory_manager.h"
#include "codon/sir/llvm/optimize.h"
namespace codon {
@ -26,7 +26,7 @@ Engine::Engine(std::unique_ptr<llvm::orc::TargetProcessControl> tpc,
: tpc(std::move(tpc)), sess(std::move(sess)), tpciu(std::move(tpciu)),
layout(std::move(layout)), mangle(*this->sess, this->layout),
objectLayer(*this->sess,
[]() { return std::make_unique<ir::BoehmGCMemoryManager>(); }),
[]() { return std::make_unique<BoehmGCMemoryManager>(); }),
compileLayer(*this->sess, objectLayer,
std::make_unique<llvm::orc::ConcurrentIRCompiler>(std::move(jtmb))),
optimizeLayer(*this->sess, compileLayer, optimizeModule),

View File

@ -3,7 +3,6 @@
#include "codon/runtime/lib.h"
namespace codon {
namespace ir {
BoehmGCMemoryManager::BoehmGCMemoryManager() : SectionMemoryManager(), roots() {}
@ -26,5 +25,4 @@ BoehmGCMemoryManager::~BoehmGCMemoryManager() {
}
}
} // namespace ir
} // namespace codon

View File

@ -6,7 +6,6 @@
#include "codon/sir/llvm/llvm.h"
namespace codon {
namespace ir {
/// Simple extension of LLVM's SectionMemoryManager which catches data section
/// allocations and registers them with the GC. This allows the GC to know not
@ -23,5 +22,4 @@ public:
~BoehmGCMemoryManager() override;
};
} // namespace ir
} // namespace codon

View File

@ -7,9 +7,10 @@
#include <unistd.h>
#include <utility>
#include "codon/compiler/debug_listener.h"
#include "codon/compiler/memory_manager.h"
#include "codon/runtime/lib.h"
#include "codon/sir/dsl/codegen.h"
#include "codon/sir/llvm/memory_manager.h"
#include "codon/sir/llvm/optimize.h"
#include "codon/util/common.h"
@ -448,9 +449,9 @@ void LLVMVisitor::run(const std::vector<std::string> &args,
EB.setMCJITMemoryManager(std::make_unique<BoehmGCMemoryManager>());
llvm::ExecutionEngine *eng = EB.create();
auto dbListener = std::unique_ptr<DebugInfoListener>();
auto dbListener = std::unique_ptr<DebugListener>();
if (db.debug) {
dbListener = std::make_unique<DebugInfoListener>();
dbListener = std::make_unique<DebugListener>();
eng->RegisterJITEventListener(dbListener.get());
}
@ -470,11 +471,8 @@ void LLVMVisitor::run(const std::vector<std::string> &args,
auto invalid = [](const std::string &name) { return name == "<invalid>"; };
fmt::print(stderr, "\n\033[1mBacktrace:\033[0m\n");
auto base = dbListener->start;
for (auto pc : e.getBacktrace()) {
auto src = sym.symbolizeCode(
*dbListener->saved.first,
{pc - base, llvm::object::SectionedAddress::UndefSection});
auto src = dbListener->symbolize(pc);
if (auto err = src.takeError())
break;
if (invalid(src->FunctionName) || invalid(src->FileName))