Git Product home page Git Product logo

debugir's Introduction

DebugIR: Debugging LLVM-IR Files

This utility revives the debug-ir pass in LLVM, but as a standalone tool. I found the idea of having a separate utility simpler after knowing that this earlier patch to revive it as a pass inside LLVM didn't go through.

Instructions

Let us assume that the LLVM-IR to be debugged is named hello.ll. Such a file can be dynamically generated, or using clang as

  clang -emit-llvm -o hello.ll -S hello.c.
hello.c
  #include <stdio.h>
  #include <string.h>

  int main(int argc, char *argv[])
  {
    if (!strcmp(argv[0], "hello")) {
      printf("Hello World\n");
    } else {
      printf("No hello\n");
    }
    return 0;
  } 

Clone and build

This tool requires LLVM-17 to be installed.

  git clone https://github.com/vaivaswatha/debugir.git debugir
  cd debugir; mkdir build; cd build
  cmake -DCMAKE_BUILD_TYPE=Release ../
  cmake --build .

If you have LLVM installed in a non-standard path, you may provide the additional CMake argument -DLLVM_DIR=/path/to/llvm.

Run

You should now have an executable file debugir in the build directory.

  ./debugir hello.ll

This produces a file hello.dbg.ll. NOTE The utility also overwrites the input LLVM-IR file (if you have comments in it, they will be lost). The new file hello.dbg.ll is semantically the same as the input file, but with debug information referring to the input file.

If you now debug hello.dbg.ll (instead of debugging hello.ll), the debugger can pickup and display hello.ll as the execution proceeds.

Note: LLVM values that don't have an explicit name cannot have their names (and hence values) seen in GDB. To workaround this, provide explicit names yourself or run the instruction namer pass by providing the -instnamer flag to debugir.

Following on the example here let us try and debug hello.dbg.ll.

  gdb --args lli -jit-kind=mcjit hello.dbg.ll
  (gdb) break hello.ll:25 # set breakpoint at line 25 in hello.ll
  (gdb) run
  lldb lli -- -jit-kind=mcjit hello.dbg.ll
  (lldb) break set -y hello.ll:25 # set breakpoint at line 25 in hello.ll
  (lldb) run

You should now hit the program at line 25 in hello.ll, assuming that line 25 is a valid line number in the LLVM source. Change this line number to an appropriate value or to a function name. Note: Since lli, at the time of invocation from gdb will not have, yet, loaded the object file for hello, you will need to set set breakpoint pending on in gdb.

debugir's People

Contributors

anton-4 avatar arkham avatar manggoguy avatar oltolm avatar vaivaswatha avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

debugir's Issues

License

Would be great if you could specify the terms of usage for the code in this repo by adding a LICENSE file.

Struct Type name issue

Hi, I've been happy using this tool.

I found the error. Sometimes, Structure type doesn't have no name because it is literal.
If there is literal struct, we can see this sentence
"debugir: IR/Type.cpp:587: llvm::StringRef llvm::StructType::getName() const: Assertion `!isLiteral() && "Literal structs never have names"' failed."
debugir should failed!

In DebugIR.cpp, "std::string getTypeName(Type *T) " should be patched.
Before T->getStructName() in the line 413, the below codes should be added

StructType* structType = dyn_cast(T);
! structType->isLiteral() ? T->getStructName() : "Literal"

And, the line 434 "(T->getStructName().str() + "." + std::to_string(tempNameCounter++))" should be patched below codes
(!structType->isLiteral()?T->getStructName().str() + "." + std::to_string(tempNameCounter++):"literal")

If you want pull request, i will

Please check!

LLVM 12 support

Hi, I've been using this tool very happily for a long time while building a compiler. Now, for various reasons, we've upgraded to llvm 12. That breaks this tool. I don't really have much familiarity with the LLVM implementation or C++ the language, so the errors are hard to interpret. How hard do you think it would be to upgrade this tool to LLVM 12? Any tips/suggestions/...?

Here's what I've tried so far. In CMakeLists.txt I've bumped the llvm version to 12. I also had to give an explicit install location for llvm but that's probably my system being weird.

There are some minor compiler errors where LLVM now uses StringRef instead of std::string, adding .str() fixes those.

Then there is this (DebugIR.cpp, line ~250) which no longer works.

DebugLoc NewLoc = DebugLoc::get(Line, Col, Scope, InlinedAt);

Looks like that constructor got removed? I think that in most cases NewLoc == Loc? There doesn't seem to be a similar constructor any more, so not sure what to do with this.

Anyway, that's all still kind of OK, but then I'm really stumped by these linker errors:

/usr/bin/ld: CMakeFiles/debugir.dir/DebugIR.cpp.o:(.data.rel.ro+0x10): undefined reference to `typeinfo for llvm::AssemblyAnnotationWriter'
/usr/bin/ld: CMakeFiles/debugir.dir/DebugIR.cpp.o:(.data.rel.ro._ZTIN4llvm18ValueMapCallbackVHIPKNS_5ValueEjNS_14ValueMapConfigIS3_NS_3sys10SmartMutexILb0EEEEEEE[_ZTIN4llvm18ValueMapCallbackVHIPKNS_5ValueEjNS_14ValueMapConfigIS3_NS_3sys10SmartMutexILb0EEEEEEE]+0x10): undefined reference to `typeinfo for llvm::CallbackVH'
/usr/bin/ld: CMakeFiles/debugir.dir/DebugIR.cpp.o:(.data.rel.ro._ZTIN4llvm18ValueMapCallbackVHIPKNS_10BasicBlockEPNS_14DILexicalBlockENS_14ValueMapConfigIS3_NS_3sys10SmartMutexILb0EEEEEEE[_ZTIN4llvm18ValueMapCallbackVHIPKNS_10BasicBlockEPNS_14DILexicalBlockENS_14ValueMapConfigIS3_NS_3sys10SmartMutexILb0EEEEEEE]+0x10): undefined reference to `typeinfo for llvm::CallbackVH'
/usr/bin/ld: CMakeFiles/debugir.dir/DebugIR.cpp.o:(.data.rel.ro._ZTIN4llvm18ValueMapCallbackVHIPKNS_8FunctionEPNS_12DISubprogramENS_14ValueMapConfigIS3_NS_3sys10SmartMutexILb0EEEEEEE[_ZTIN4llvm18ValueMapCallbackVHIPKNS_8FunctionEPNS_12DISubprogramENS_14ValueMapConfigIS3_NS_3sys10SmartMutexILb0EEEEEEE]+0x10): undefined reference to `typeinfo for llvm::CallbackVH'
/usr/bin/ld: CMakeFiles/debugir.dir/DebugIR.cpp.o:(.data.rel.ro._ZTIN4llvm18ValueMapCallbackVHIPKNS_5ValueENS_14WeakTrackingVHENS_14ValueMapConfigIS3_NS_3sys10SmartMutexILb0EEEEEEE[_ZTIN4llvm18ValueMapCallbackVHIPKNS_5ValueENS_14WeakTrackingVHENS_14ValueMapConfigIS3_NS_3sys10SmartMutexILb0EEEEEEE]+0x10): undefined reference to `typeinfo for llvm::CallbackVH'
/usr/bin/ld: CMakeFiles/debugir.dir/Main.cpp.o:(.data.rel.ro._ZTIN4llvm2cl15OptionValueCopyINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE[_ZTIN4llvm2cl15OptionValueCopyINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE]+0x10): undefined reference to `typeinfo for llvm::cl::GenericOptionValue'
/usr/bin/ld: CMakeFiles/debugir.dir/Main.cpp.o:(.data.rel.ro._ZTIN4llvm2cl15OptionValueCopyIbEE[_ZTIN4llvm2cl15OptionValueCopyIbEE]+0x10): undefined reference to `typeinfo for llvm::cl::GenericOptionValue'
collect2: error: ld returned 1 exit status

maybe relevant detail: my llvm "installation" is an archive downloaded from the llvm github. The install script does not seem to work on my version of ubuntu. Crucially that archive does not seem to contain the .cpp files, so maybe that's the problem?

LLVM 15 support

the code mostly works with llvm 15, except one occurence of getPointerElementType

    } else if (T->isPointerTy()) {
      Type *PointeeTy = T->getPointerElementType();
      if (!(N = getType(PointeeTy)))
        N = Builder.createPointerType(
            getOrCreateType(PointeeTy), Layout.getPointerTypeSizeInBits(T),
            Layout.getPrefTypeAlignment(T), /*DWARFAddressSpace=*/None,
            getTypeName(T));

llvm 15 makes opaque pointers the default, and those don't have getPointerElementType any more. With this piece of code commented the build succeeds, but I'm not sure what consequences that has for the tool actually functioning.

Conflicting licenses

I was looking through the different files in the repo and noticed an issue, the Main.cpp has a GPLv3 license, but the project has an Apache 2 license. I don't think this is legally valid. It looks like you chose the license in Main.cpp, my personal preference would be remove the GPLv3 license on Main.cpp and let it fall under the project Apache 2 license. Because GPL licenses make things a lot more complicated.

Opaque struct type issue

Hi, I've been happy using this tool.

I found the error. Sometimes, some struct type are opaque like this
%struct._IO_marker = type opaque
If there is opaque struct type, we can see this sentence
"debugir: /home/mok/llvm/llvm-11.0.0.src/lib/IR/DataLayout.cpp:713: llvm::Align llvm::DataLayout::getAlignment(llvm::Type*, bool) const: Assertion `Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!"' failed."
debugir should failed!

In DebugIR.cpp, the problem occurs in function "DIType *getOrCreateType(Type *T)"
At line 413,

DICompositeType *S = Builder.createStructType( LexicalBlockFileNode, ST->hasName()? T->getStructName():"literal", FileNode, /*LineNumber=*/0, Layout.getTypeSizeInBits(T), Layout.getABITypeAlignment(T), /*DIFlags=*/llvm::DINode::FlagZero, /*DerivedFrom=*/nullptr, llvm::DINodeArray()); // filled in later
The problem occurs when calling "Layout.getTypeSizeInBits(T)"
I fix the only the line, but error occurs behind.

In my opinion, we should separate it into cases where the type is opaque and cases where it is not.
Do you have any idea?

Please check!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.