Giter VIP home page Giter VIP logo

stoat's Introduction

stoat logo

Stoat - Realtime Function Static Analysis

Stoat is a tool to assert properties about the callgraph of programs/libraries. The primary usage of this tool is to analyze programs which need to perform hard realtime operations in a portion of a mixed codebase. This is done by identifying all functions which can transitively be called from some known root function which must be realtime. If any unsafe function which could block for an arbitrary amount of time is found in this transitive closure, then an error is emitted to indicate where the improper behavior can be found and what backtrace is responsible for it getting called.

Why?

Maintaining a large codebase in C/C++ can make it very difficult to know what code ends up calling what other routines. This is further complicated when there is some segregation within one codebase which may not be at all clear in implementation. This is further complicated by the opaqueness of some C++ techniques, such as virtual overloading, operator overloading, multiple inheritance, and implicit conversions.

Requires

  • LLVM 3.3+

  • Clang 3.3+

  • c++filt

  • ruby

  • graphviz gem (OPTIONAL) for callgraph renderings

  • colorize gem (OPTIONAL) for colored output

How To Build

git clone https://github.com/fundamental/stoat && cd stoat
mkdir build && cd build
cmake .. && make && make test
make install #or just run in place

Features

  • Inline safety markers __attribute__((annotate("realtime")))

  • Inline hazard markers __attribute__((annotate("non-realtime")))

  • Out-of-line whitelists/blacklists

  • Out-of-line suppression files

  • Graph capabilities for safe or contradicting graph

  • Support for dispatch tree analysis within librtosc

How To Use

  1. Annotate a root realtime function with __attribute__((annotate("realtime")))

  2. Compile all files with CC=stoat-compile CXX=stoat-compile++ or just compile files with clang’s -emit-llvm flag

  3. Run the stoat on the resulting llvm IR files using the --recursive option

  4. View the contradictions

  5. Optionally redo the analysis using the -G option to graphically view the contradictions

  6. Update your code, a whitelist, or suppression list

  7. Enjoy the safer code

For a more explicit guide please see the tutorial at http://log.fundamental-code.com/2014/08/15/stoat-tutorial-example.html

License

Stoat is available under the GPLv3 license

stoat's People

Contributors

alex-tee avatar dsacre avatar falktx avatar fundamental avatar johanneslorenz avatar simonvanderveldt avatar ventosus 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

Watchers

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

stoat's Issues

Error in suppressions mechanism

A suppression file

a ==> A
b ==> B

will not only suppress calls from a to A and from b to B,

but will also suppress calls from a to B and from b to A

in the current implementation.

Ruby error in create_alias_map

MacOS 10.12.6 with Ruby 2.5.0

/usr/local/share/stoat/load-callgraph.rb:117:in `block in create_alias_map': undefined method `each' for #<String:0x007feafb873118> (NoMethodError)
	from /usr/local/share/stoat/load-callgraph.rb:116:in `each'
	from /usr/local/share/stoat/load-callgraph.rb:116:in `create_alias_map'
	from /usr/local/share/stoat/load-callgraph.rb:55:in `block in load_callgraph'
	from /usr/local/share/stoat/load-callgraph.rb:26:in `each'
	from /usr/local/share/stoat/load-callgraph.rb:26:in `load_callgraph'
	from /usr/local/bin/stoat:262:in `<main>'

build fails on macOS Sierra and homebrew LLVM

macOS uses Clang as the default compiler for the platform but omits LLVM tools required to build this project. The homebrew package manager provides LLVM with an option to use environment variables for programs like stoat which need to link to LLVM libraries. Building fails with the following output. My system details follow.

[lazzarello@strop build (master)]$ cmake ..
-- The C compiler identification is AppleClang 8.0.0.8000042
-- The CXX compiler identification is AppleClang 8.0.0.8000042
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found LLVM: -lLLVMLTO -lLLVMPasses -lLLVMObjCARCOpts -lLLVMSymbolize -lLLVMDebugInfoPDB -lLLVMDebugInfoDWARF -lLLVMMIRParser -lLLVMCoverage -lLLVMTableGen -lLLVMDlltoolDriver -lLLVMOrcJIT -lLLVMXCoreDisassembler -lLLVMXCoreCodeGen -lLLVMXCoreDesc -lLLVMXCoreInfo -lLLVMXCoreAsmPrinter -lLLVMSystemZDisassembler -lLLVMSystemZCodeGen -lLLVMSystemZAsmParser -lLLVMSystemZDesc -lLLVMSystemZInfo -lLLVMSystemZAsmPrinter -lLLVMSparcDisassembler -lLLVMSparcCodeGen -lLLVMSparcAsmParser -lLLVMSparcDesc -lLLVMSparcInfo -lLLVMSparcAsmPrinter -lLLVMPowerPCDisassembler -lLLVMPowerPCCodeGen -lLLVMPowerPCAsmParser -lLLVMPowerPCDesc -lLLVMPowerPCInfo -lLLVMPowerPCAsmPrinter -lLLVMNVPTXCodeGen -lLLVMNVPTXDesc -lLLVMNVPTXInfo -lLLVMNVPTXAsmPrinter -lLLVMMSP430CodeGen -lLLVMMSP430Desc -lLLVMMSP430Info -lLLVMMSP430AsmPrinter -lLLVMMipsDisassembler -lLLVMMipsCodeGen -lLLVMMipsAsmParser -lLLVMMipsDesc -lLLVMMipsInfo -lLLVMMipsAsmPrinter -lLLVMLanaiDisassembler -lLLVMLanaiCodeGen -lLLVMLanaiAsmParser -lLLVMLanaiDesc -lLLVMLanaiAsmPrinter -lLLVMLanaiInfo -lLLVMHexagonDisassembler -lLLVMHexagonCodeGen -lLLVMHexagonAsmParser -lLLVMHexagonDesc -lLLVMHexagonInfo -lLLVMBPFDisassembler -lLLVMBPFCodeGen -lLLVMBPFDesc -lLLVMBPFInfo -lLLVMBPFAsmPrinter -lLLVMARMDisassembler -lLLVMARMCodeGen -lLLVMARMAsmParser -lLLVMARMDesc -lLLVMARMInfo -lLLVMARMAsmPrinter -lLLVMAMDGPUDisassembler -lLLVMAMDGPUCodeGen -lLLVMAMDGPUAsmParser -lLLVMAMDGPUDesc -lLLVMAMDGPUInfo -lLLVMAMDGPUAsmPrinter -lLLVMAMDGPUUtils -lLLVMAArch64Disassembler -lLLVMAArch64CodeGen -lLLVMAArch64AsmParser -lLLVMAArch64Desc -lLLVMAArch64Info -lLLVMAArch64AsmPrinter -lLLVMAArch64Utils -lLLVMObjectYAML -lLLVMLibDriver -lLLVMOption -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMGlobalISel -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMDebugInfoCodeView -lLLVMDebugInfoMSF -lLLVMX86Desc -lLLVMMCDisassembler -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMMCJIT -lLLVMLineEditor -lLLVMInterpreter -lLLVMExecutionEngine -lLLVMRuntimeDyld -lLLVMCodeGen -lLLVMTarget -lLLVMCoroutines -lLLVMipo -lLLVMInstrumentation -lLLVMVectorize -lLLVMScalarOpts -lLLVMLinker -lLLVMIRReader -lLLVMAsmParser -lLLVMInstCombine -lLLVMTransformUtils -lLLVMBitWriter -lLLVMAnalysis -lLLVMProfileData -lLLVMObject -lLLVMMCParser -lLLVMMC -lLLVMBitReader -lLLVMCore -lLLVMBinaryFormat -lLLVMSupport -lLLVMDemangle;-L/usr/local/Cellar/llvm/5.0.0/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names (found version "5.0.0") 
statusBuild Flags ' -I/usr/local/Cellar/llvm/5.0.0/include   -DLLVM_BUILD_GLOBAL_ISEL -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -fno-rtti -std=c++11'
-- Configuring done
CMake Warning (dev):
  Policy CMP0042 is not set: MACOSX_RPATH is enabled by default.  Run "cmake
  --help-policy CMP0042" for policy details.  Use the cmake_policy command to
  set the policy and suppress this warning.

  MACOSX_RPATH is not specified for the following targets:

   stoat

This warning is for project developers.  Use -Wno-dev to suppress it.

-- Generating done
-- Build files have been written to: /Users/lazzarello/src/stoat/build
[lazzarello@strop build (master)]$ make
Scanning dependencies of target stoat
[ 50%] Building CXX object CMakeFiles/stoat.dir/src/llvm-passes.cpp.o
/Users/lazzarello/src/stoat/src/llvm-passes.cpp:536:45: error: no member named 'getArgumentList' in
      'llvm::Function'
                std::string alias_type = Fn.getArgumentList().front().getType()->getPointerElementTyp...
                                         ~~ ^
1 error generated.
make[2]: *** [CMakeFiles/stoat.dir/src/llvm-passes.cpp.o] Error 1
make[1]: *** [CMakeFiles/stoat.dir/all] Error 2
make: *** [all] Error 2

system info

[lazzarello@strop stoat (master)]$ llvm-config --version
5.0.0
[lazzarello@strop stoat (master)]$ clang --version
clang version 5.0.0 (tags/RELEASE_500/final)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin
[lazzarello@strop stoat (master)]$ cmake --version
cmake version 3.10.0

CMake suite maintained and supported by Kitware (kitware.com/cmake).

Hack Vtable Support

It is pretty idiotic, however it looks like the only way to establish any information about virtual method calls is to rebuild the vtable ourselves.

With a module pass it is possible to find all of the symbols that correspond to the vtable entries.
This should provide a function lookup scheme.

This however only takes care of part of the problem.
Knowing the vtables for "class B:public A" works fine when you are calling B's methods, but it fails hard when an A pointer is used.

This problem means that some hackery needs to be done within constructors to identify superclasses as well.
This seems reasonably easy to find as there are bitcast instructions which convert the "this" pointer from subclass type to superclass type within the subclass's constructor.
The only issue is identifying the constructor, which might need some understanding of the mangling functions.

Once the class hierarchy is known and the vtables are reconstructed, then a call to a function which cannot be resolved should be checkable against some relatively fixed patterns for vtable+offset .

Some extra caution will be needed to avoid any mistaken reports of calling __cxa_pure_virtual

As a rough idea as to what might get printed on the functioncall trace list

function trace:

- foobar
    - A::vtable::0

vtable definitions

- A::vtable::0
    - __cxa_pure_virtual
- A::vtable::1
   - asdf
- B::vtable::0
   - blam

Class Definition

- B :
 - A

Oh boy is this going to be fun :p

Error when trying to install on gentoo because of ldconfig invocation

Hi Mark, first of all it was very nice meeting you @ LAC!
As I already mentioned there thanks for this tool. I'm working on packaging it for gentoo and ran into the following issue when building it:

...
Install the project...
-- Install configuration: "Gentoo"
-- Installing: /var/tmp/portage/dev-util/stoat-9999/image/usr/lib/libstoat.so
-- Installing: /var/tmp/portage/dev-util/stoat-9999/image/usr/bin/stoat
-- Installing: /var/tmp/portage/dev-util/stoat-9999/image/usr/bin/stoat-compile
-- Installing: /var/tmp/portage/dev-util/stoat-9999/image/usr/bin/stoat-compile++
-- Installing: /var/tmp/portage/dev-util/stoat-9999/image/usr/share/stoat/callgraph.rb
-- Installing: /var/tmp/portage/dev-util/stoat-9999/image/usr/share/stoat/deductions.rb
-- Installing: /var/tmp/portage/dev-util/stoat-9999/image/usr/share/stoat/graph.rb
-- Installing: /var/tmp/portage/dev-util/stoat-9999/image/usr/share/stoat/load-callgraph.rb
-- Installing: /var/tmp/portage/dev-util/stoat-9999/image/usr/share/stoat/whitelist.txt
-- Installing: /var/tmp/portage/dev-util/stoat-9999/image/usr/share/stoat/blacklist.txt
 * ACCESS DENIED:  open_wr:      /etc/ld.so.cache~
CMake Warning at /var/tmp/portage/dev-util/stoat-9999/work/stoat-9999/cmake/InstallScript.cmake:8 (message):
  Warning: ldconfig 1

Call Stack (most recent call first):
  cmake_install.cmake:76 (include)


CMake Warning at /var/tmp/portage/dev-util/stoat-9999/work/stoat-9999/cmake/InstallScript.cmake:9 (message):
           You may need to manually specify --llvm-passes
Call Stack (most recent call first):
  cmake_install.cmake:76 (include)


>>> Completed installing stoat-9999 into /var/tmp/portage/dev-util/stoat-9999/image/

 * Final size of build directory: 971 KiB
 * Final size of installed tree: 10 KiB

 * --------------------------- ACCESS VIOLATION SUMMARY ---------------------------
 * LOG FILE: "/var/log/sandbox/sandbox-7282.log"
 * 
VERSION 1.0
FORMAT: F - Function called
FORMAT: S - Access Status
FORMAT: P - Path as passed to function
FORMAT: A - Absolute Path (not canonical)
FORMAT: R - Canonical Path
FORMAT: C - Command Line

F: open_wr
S: deny
P: /etc/ld.so.cache~
A: /etc/ld.so.cache~
R: /etc/ld.so.cache~
C: ldconfig 
 * --------------------------------------------------------------------------------

The error you're seeing is from the gentoo sandbox which is there to guarantee a clean build environment and ensure the build doesn't do anything with files it shouldn't have access to. In this case ldconfig is trying to write to /etc/ld.so.cache, which is not allowed in the sandbox.

This is caused by this script https://github.com/fundamental/stoat/blob/master/cmake/InstallScript.cmake

Was there any particular reason you added this? Normally the package manager would run ldconfig if new libraries are installed, it's not something the build system normally does.

Graphviz generation error with 2.38.0

Hi,

I'm encountering an error on using the --graph-view switch, in a simple one file main.c test using:

stoat -r . --graph-view graph.png

Error is as follows:

Error #1:
main
##The Deduction Chain:
##The Contradiction Reasons:
 - printf : Assumed Unsafe

Total of 1 error(s)
Total Functions:   3
Total Realtime:    1
Total NonRealtime: 1
Parsing './main.bc'...
/usr/share/stoat/graph.rb:51:in `to_graph': uninitialized constant GraphRender::GraphViz (NameError)
    from /usr/bin/stoat:312:in `<main>'

I'm on Arch linux with Graphviz current, and just ran gem install graphviz.. perhaps there's a mismatch there? I'm no Ruby coder - so I'm not sure. Cheers, -Harry

RT-Safe classes based on non-rt safe ones ignore higher-level implementation

In Carla I have a base class for a linked list which allocates on heap.
I override the allocation methods in a new rt-safe class with a memory pool.

The following code uses such class https://github.com/falkTX/Carla/blob/01b50d2f0ba44f4e98e2ae75082a0a465116d9ef/source/backend/plugin/CarlaPluginInternal.hpp#L253

stoat seems to be getting confused by this.
Reports the following error:

Error #26:
LinkedList<CarlaBackend::PluginPostRtEvent>::_allocate() _ZN10LinkedListIN12CarlaBackend17PluginPostRtEventEE9_allocateEv
##The Deduction Chain:
 - LinkedList<CarlaBackend::PluginPostRtEvent>$vtable2 : Deduced Realtime
 - AbstractLinkedList<CarlaBackend::PluginPostRtEvent>$vtable2 : Deduced Realtime
 - AbstractLinkedList<CarlaBackend::PluginPostRtEvent>::_add(CarlaBackend::PluginPostRtEvent const&, bool, AbstractLinkedList<CarlaBackend::PluginPostRtEvent>::ListHead*) _ZN18AbstractLinkedListIN12CarlaBackend17PluginPostRtEventEE4_addERKS1_bPNS2_8ListHeadE : Deduced Realtime
 - AbstractLinkedList<CarlaBackend::PluginPostRtEvent>::append(CarlaBackend::PluginPostRtEvent const&) _ZN18AbstractLinkedListIN12CarlaBackend17PluginPostRtEventEE6appendERKS1_ : Deduced Realtime
 - CarlaBackend::CarlaPlugin::ProtectedData::PostRtEvents::appendRT(CarlaBackend::PluginPostRtEvent const&) _ZN12CarlaBackend11CarlaPlugin13ProtectedData12PostRtEvents8appendRTERKNS_17PluginPostRtEventE : Deduced Realtime
 - CarlaBackend::CarlaPlugin::ProtectedData::postponeRtEvent(CarlaBackend::PluginPostRtEventType, int, int, float) _ZN12CarlaBackend11CarlaPlugin13ProtectedData15postponeRtEventENS_21PluginPostRtEventTypeEiif : Deduced Realtime
 - CarlaBackend::CarlaPluginDSSI::process(float const**, float**, float const**, float**, unsigned int) _ZN12CarlaBackend15CarlaPluginDSSI7processEPPKfPPfS3_S5_j : Deduced Realtime
 - CarlaBackend::CarlaPluginDSSI$vtable40 : Deduced Realtime
 - CarlaBackend::CarlaPlugin$vtable40 : Deduced Realtime
 - CarlaBackend::CarlaEngineJack::processPlugin(CarlaBackend::CarlaPlugin*, unsigned int) _ZN12CarlaBackend15CarlaEngineJack13processPluginEPNS_11CarlaPluginEj : Deduced Realtime
 - CarlaBackend::CarlaEngineJack::handleJackProcessCallback(unsigned int) _ZN12CarlaBackend15CarlaEngineJack25handleJackProcessCallbackEj : Deduced Realtime
 - CarlaBackend::CarlaEngineJack::carla_jack_process_callback(unsigned int, void*) _ZN12CarlaBackend15CarlaEngineJack27carla_jack_process_callbackEjPv : Realtime (Annotation)
##The Contradiction Reasons:
 - malloc : NonRealtime (Blacklist)

Add Line Numbers

When building with -g clang produces information which should be mappable back to line numbers and whatnot.

  • Add line number/file information to nodes in yaml printout (it might be worth a format redesign to avoid parsing hell)
  • Add line number information to callgraph node and callgraph edge information
  • Preserve information about the relevant calls in the deduction phase
  • Add line number/file information to the output errors and the deduction change

Demangled names can exceed YAML's 1024 character key limit

YAML (and Ruby's YAML parser) has a key length limit of 1024 characters. I hit this limit running stoat on mididings:

Parsing 'src/python_module.o.bc'...
/usr/lib/ruby/1.9.1/psych.rb:203:in `parse': (stoat_vtable.txt): could not find expected ':' while scanning a simple key at line 37 column 1 (Psych::SyntaxError)
    from /usr/lib/ruby/1.9.1/psych.rb:203:in `parse_stream'
    from /usr/lib/ruby/1.9.1/psych.rb:151:in `parse'
    from /usr/lib/ruby/1.9.1/psych.rb:127:in `load'
    from /usr/lib/ruby/1.9.1/psych.rb:297:in `block in load_file'
    from /usr/lib/ruby/1.9.1/psych.rb:297:in `open'
    from /usr/lib/ruby/1.9.1/psych.rb:297:in `load_file'
    from /usr/local/share/stoat/load-callgraph.rb:52:in `block in load_callgraph'
    from /usr/local/share/stoat/load-callgraph.rb:26:in `each'
    from /usr/local/share/stoat/load-callgraph.rb:26:in `load_callgraph'
    from /usr/local/bin/stoat:262:in `<main>'

The key is nothing fancy really, just a function taking a map<string, vector<string>>, wrapped with Boost.Python...:

boost::python::objects::caller_py_function_impl<boost::python::detail::caller<void (mididings::backend::BackendBase::*)(std::map<std::string, std::vector<std::string, std::allocator<std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::vector<std::string, std::allocator<std::string> > > > > const&, std::map<std::string, std::vector<std::string, std::allocator<std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::vector<std::string, std::allocator<std::string> > > > > const&), boost::python::default_call_policies, boost::mpl::vector4<void, mididings::backend::BackendBase&, std::map<std::string, std::vector<std::string, std::allocator<std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::vector<std::string, std::allocator<std::string> > > > > const&, std::map<std::string, std::vector<std::string, std::allocator<std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::vector<std::string, std::allocator<std::string> > > > > const&> > >

My current workaround is to simply change ExtractVtables::handleVtable() to shorten names to 1024 characters (the function in question is not relevant to realtime-issues anyway). Is there a better solution, other than changing stoat's vtable file format?

More vtable Chasing

There's yet another case that can result in a dangling $vtable in '[email protected]:JohannesLorenz/minimal.git'

This issue has to be investigated and then reclassified once the nature of the bug is known.

Crash on Clang 4.0.0 (arch)

ExtractVtables::runOnModule in diamond confuse test case. I'd wager the crash is actually in handleVTable. Updating slackware should allow me to test this version. (currently tested with clang 3.7.0 and everything passes)

Functions with same name in multiple compilation targets do not increase counters

I have some functions with the same name in multiple plugin-like .so files.

I annotated the first and it picked it up and reported a number of realtime functions, when the second was annotated that number did not change. Renaming the function caused the count to increase.

This may well be intentional (and my own fault for running across multiple targets), but I thought it might be worth asking about.

Ingen Build Results In Unparsed Vtable Entries

After running stoat on Ingen the following symbol calls no functions: Ingen::Server::PortImpl$vtable35
This is either a bug in vtable extraction or in the case of pure virtuals a bug in identifying subclasses.

Use trivial data-dependencies to ignore non-rt functions with trivial conditionals

Note sure how to title this.

Take the following code:
https://github.com/falkTX/Carla/blob/01b50d2f0ba44f4e98e2ae75082a0a465116d9ef/source/backend/plugin/CarlaPlugin.cpp#L1306
There's 2 boolean arguments - sendOsc and sendCallback.
This function is called from RT side, but with those arguments as false.
For example here: https://github.com/falkTX/Carla/blob/01b50d2f0ba44f4e98e2ae75082a0a465116d9ef/source/backend/plugin/CarlaPluginLADSPA.cpp#L968

Hopefully it's possible to detect the cases where the code obviously is not being run, like calling a function with 'false' directly, as in the examples.
Carla's stoat output is 75% filled with stuff like this.

LLVM Pass may be broken under LLVM 5.0.1

It looks like they've changed their API slightly for LLVM 5. Currently the LLVM pass has a chance to throw:

 /usr/include/llvm-5.0/llvm/IR/Type.h:363: llvm::Type* llvm::Type::getArrayElementType() const: Assertion `getTypeID() == ArrayTyID' failed

Add type checks when loading the YAML from the LLVM pass

Some typechecks and exception handling should be added to the YAML loading to provide clear errors and debugging information when the ruby layer reads in malformed files produced by the LLVM passes. See #38 as an example of one case where these improved errors would have helped.

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.