DependableSystemsLab / LLFI

LLFI is an LLVM based fault injection tool, that injects faults into the LLVM IR of the application source code. The faults can be injected into specific program points, and the effect can be easily tracked back to the source code. Please refer to the paper below. NOTE: If you publish a paper using LLFI, please add it to PaperLLFI.bib
http://blogs.ubc.ca/karthik/2014/02/23/quantifying-the-accuracy-of-high-level-fault-injection-techniques/
Other
66 stars 36 forks source link

Problems when using LLFI with a OpenCV-based program #122

Closed LucaCassano closed 3 years ago

LucaCassano commented 5 years ago

Hi everybody, I am a beginner LLFI user, thus, maybe this is a trivial issue. Sorry in the case.

I would like to analyse with LLFI deconv.cpp which is the following:

include "opencv2/opencv.hpp"

include

using namespace cv; using namespace std;

static int image_type;

Mat RL_deconvolution(Mat observed, Mat psf, int iterations) {

Scalar grey;

// Uniform grey starting estimation
switch (image_type) {
    case CV_64FC1:
        grey = Scalar(0.5);
    case CV_64FC3:
        grey = Scalar(0.5, 0.5, 0.5);
}
Mat latent_est = Mat(observed.size(), image_type, grey);

// Flip the point spread function (NOT the inverse)
Mat psf_hat = Mat(psf.size(), CV_64FC1);
int psf_row_max = psf.rows - 1;
int psf_col_max = psf.cols - 1;
for (int row = 0; row <= psf_row_max; row++) {
    for (int col = 0; col <= psf_col_max; col++) {
        psf_hat.at<double>(psf_row_max - row, psf_col_max - col) =
            psf.at<double>(row, col);
    }
}

Mat est_conv;
Mat relative_blur;
Mat error_est;

// Iterate
for (int i=0; i<iterations; i++) {

    filter2D(latent_est, est_conv, -1, psf);

    // Element-wise division
    relative_blur = observed.mul(1.0/est_conv);

    filter2D(relative_blur, error_est, -1, psf_hat);

    // Element-wise multiplication
    latent_est = latent_est.mul(error_est);
}

return latent_est;

}

int main( int argc, const char** argv ) { if (argc != 4) { cout << "Usage: " << argv[0] << " image_name #iterations blurring_level"<< "\n"; return -1; }

int iterations = atoi(argv[2]);
int smoothing_level = atoi(argv[3]);

// Read the original image
Mat original_image;
original_image = imread(argv[1], CV_LOAD_IMAGE_UNCHANGED);

int num_channels = original_image.channels();
switch (num_channels) {
    case 1:
        image_type = CV_64FC1;
        break;
    case 3:
        image_type = CV_64FC3;
        break;
    default:
        return -2;
}

// This is a hack, assumes too much
int divisor;
switch (original_image.elemSize() / num_channels) {
    case 1:
        divisor = 255;
        break;
    case 2:
        divisor = 65535;
        break;
    default:
        return -3;
}

// From here on, use 64-bit floats
// Convert original_image to float
Mat float_image;
original_image.convertTo(float_image, image_type);
float_image *= 1.0/divisor;
//imwrite("./Float.jpg", float_image);

// Calculate a gaussian blur psf.
double sigma_row = 9.0;
double sigma_col = 5.0;

// change this param to change the smoothing factor
int psf_size = smoothing_level;

double mean_row = 0.0;
double mean_col = psf_size/2.0;
double sum = 0.0;
double temp;
Mat psf = Mat(Size(psf_size, psf_size), CV_64FC1, 0.0);

for (int j = 0; j<psf.rows; j++) {
    for (int k = 0; k<psf.cols; k++) {
        temp = exp(
                -0.5 * (
                    pow((j - mean_row) / sigma_row, 2.0) + 
                    pow((k - mean_col) / sigma_col, 2.0))) /
            (2* M_PI * sigma_row * sigma_col);
        sum += temp;
        psf.at<double>(j,k) = temp;
    }
}

// Normalise the psf.
for (int row = 0; row<psf.rows; row++) {
    for (int col = 0; col<psf.cols; col++) {
        psf.at<double>(row, col) /= sum;
    }
}

Mat estimation = RL_deconvolution(float_image, psf, iterations);
estimation.convertTo(estimation, CV_8UC3, 255.0); 
imwrite("./Estimation.bmp", estimation);

return 0;

}

It's normal compilation command would be: g++ -g deconv.cpp -o pkg-config --cflags --libs opencv

First of all: I do not know how to specify the pkg-config --cflags --libs opencv option in LLFI.

Anyways, the "Compile To IT" step seems to work, but then, when trying to intrument the code, I get error with the following error log:

; ModuleID = 'deconv.ll' target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu"

%"class.std::ios_base::Init" = type { i8 } %"class.std::basic_ostream" = type { i32 (...), %"class.std::basic_ios" } %"class.std::basic_ios" = type { %"class.std::ios_base", %"class.std::basic_ostream", i8, i8, %"class.std::basic_streambuf", %"class.std::ctype", %"class.std::num_put", %"class.std::num_get"* } %"class.std::ios_base" = type { i32 (...)*, i64, i64, i32, i32, i32, %"struct.std::ios_base::_Callback_list", %"struct.std::ios_base::_Words", [8 x %"struct.std::ios_base::_Words"], i32, %"struct.std::ios_base::_Words", %"class.std::locale" } %"struct.std::ios_base::_Callback_list" = type { %"struct.std::ios_base::_Callback_list", void (i32, %"class.std::ios_base", i32), i32, i32 } %"struct.std::ios_base::_Words" = type { i8, i64 } %"class.std::locale" = type { %"class.std::locale::_Impl" } %"class.std::locale::_Impl" = type { i32, %"class.std::locale::facet", i64, %"class.std::locale::facet", i8 } %"class.std::locale::facet" = type { i32 (...), i32 } %"class.std::basic_streambuf" = type { i32 (...), i8, i8, i8, i8, i8, i8, %"class.std::locale" } %"class.std::ctype" = type { %"class.std::locale::facet", %struct.locale_struct, i8, i32, i32, i16, i8, [256 x i8], [256 x i8], i8 } %struct.__locale_struct = type { [13 x %struct.locale_data], i16, i32, i32, [13 x i8*] } %struct.locale_data = type opaque %"class.std::num_put" = type { %"class.std::locale::facet" } %"class.std::num_get" = type { %"class.std::locale::facet" } %"struct.cvflann::anyimpl::big_any_policy" = type { %"struct.cvflann::anyimpl::typed_base_any_policy" } %"struct.cvflann::anyimpl::typed_base_any_policy" = type { %"struct.cvflann::anyimpl::base_any_policy" } %"struct.cvflann::anyimpl::base_any_policy" = type { i32 (...) } %"struct.cvflann::anyimpl::small_any_policy" = type { %"struct.cvflann::anyimpl::typed_base_any_policy.0" } %"struct.cvflann::anyimpl::typed_base_any_policy.0" = type { %"struct.cvflann::anyimpl::base_any_policy" } %"struct.cvflann::anyimpl::small_any_policy.1" = type { %"struct.cvflann::anyimpl::typed_base_any_policy.2" } %"struct.cvflann::anyimpl::typed_base_any_policy.2" = type { %"struct.cvflann::anyimpl::base_any_policy" } %"struct.cvflann::anyimpl::small_any_policy.3" = type { %"struct.cvflann::anyimpl::typed_base_any_policy.4" } %"struct.cvflann::anyimpl::typed_base_any_policy.4" = type { %"struct.cvflann::anyimpl::base_any_policy" } %"struct.cvflann::anyimpl::small_any_policy.5" = type { %"struct.cvflann::anyimpl::typed_base_any_policy.6" } %"struct.cvflann::anyimpl::typed_base_any_policy.6" = type { %"struct.cvflann::anyimpl::base_any_policy" } %"struct.cvflann::anyimpl::big_any_policy.7" = type { %"struct.cvflann::anyimpl::typed_base_any_policy.8" } %"struct.cvflann::anyimpl::typed_base_any_policy.8" = type { %"struct.cvflann::anyimpl::base_any_policy" } %"struct.cvflann::anyimpl::big_any_policy.9" = type { %"struct.cvflann::anyimpl::typed_base_any_policy.10" } %"struct.cvflann::anyimpl::typed_base_any_policy.10" = type { %"struct.cvflann::anyimpl::base_any_policy" } %"struct.cvflann::anyimpl::small_any_policy.11" = type { %"struct.cvflann::anyimpl::typed_base_any_policy.12" } %"struct.cvflann::anyimpl::typed_base_any_policy.12" = type { %"struct.cvflann::anyimpl::base_any_policy" } %"struct.cvflann::anyimpl::big_any_policy.13" = type { %"struct.cvflann::anyimpl::typed_base_any_policy.14" } %"struct.cvflann::anyimpl::typed_base_any_policy.14" = type { %"struct.cvflann::anyimpl::base_any_policy" } %"class.cv::Mat" = type { i32, i32, i32, i32, i8, i8, i8, i8, %"class.cv::MatAllocator", %"struct.cv::UMatData", %"struct.cv::MatSize", %"struct.cv::MatStep" } %"class.cv::MatAllocator" = type { i32 (...) } %"struct.cv::UMatData" = type { %"class.cv::MatAllocator", %"class.cv::MatAllocator", i32, i32, i8, i8, i64, i32, i8, i8, i32, i32, %"struct.cv::UMatData" } %"struct.cv::MatSize" = type { i32 } %"struct.cv::MatStep" = type { i64, [2 x i64] } %"class.cv::Scalar" = type { %"class.cv::Vec" } %"class.cv::Vec" = type { %"class.cv::Matx" } %"class.cv::Matx" = type { [4 x double] } %"class.cv::Size" = type { i32, i32 } %"class.cv::_InputArray" = type { i32, i8, %"class.cv::Size_" } %"class.cv::_OutputArray" = type { %"class.cv::InputArray" } %"class.cv::Point" = type { i32, i32 } %"class.cv::MatExpr" = type { %"class.cv::MatOp"*, i32, %"class.cv::Mat", %"class.cv::Mat", %"class.cv::Mat", double, double, %"class.cv::Scalar_" } %"class.cv::MatOp" = type { i32 (...) } %"class.cv::String" = type { i8, i64 } %"class.std::vector" = type { %"struct.std::_Vector_base" } %"struct.std::_Vector_base" = type { %"struct.std::_Vector_base<int, std::allocator >::_Vector_impl" } %"struct.std::_Vector_base<int, std::allocator >::_Vector_impl" = type { i32, i32, i32 } %"class.std::allocator" = type { i8 } %"class.std::type_info" = type { i32 (...), i8* } %"class.gnu_cxx::new_allocator" = type { i8 } %"struct.cvflann::anyimpl::empty_any" = type { i8 }

[.......]

Is there anything you could explain to me?

Best regards, Luca

lpalazzi commented 5 years ago

Hi Luca,

Could you e-mail me the source code? I'll try it out on my machine and see if I can get it to work. E-mail is lpalazzi@ece.ubc.ca

Thanks, Lucas