Getting Segmentation fault while retrieving values at runtime

Using this code, I am getting a segmentation fault while retrieving the values. Following pass code is trying to access some values that it was not suppose to access in this file on this line,

#ifdef CLIENT_MPO
				pcli->publishStationBroadcast("MPO",
#elif CLIENT_HBW
				pcli->publishStationBroadcast("HBW",
#elif CLIENT_VGR
				pcli->publishStationBroadcast("VGR",
#elif CLIENT_SLD
				pcli->publishStationBroadcast("SLD",
#else
				#error Set CLIENT_XXX define first!

Here is the pass,

 for (auto &F:M){
                std::vector<std::string> arg_strings;
                std::vector<Value*> arg_values;
                std::string s;
                raw_string_ostream rso(s);
                rso << F.getName() << " ";
                arg_strings.push_back(rso.str());
                for(auto i = F.arg_begin();i!=F.arg_end();++i){
                        //errs()<<"\narg_strings: "<<*i<< ", name = " << i->getName() <<"\n";
                        //std::string s;
                        //raw_string_ostream rso(s);
                        rso << *i <<"\n";
                        arg_strings.push_back(rso.str());
                        arg_values.push_back(i);
                }
                if(F.getName().contains("message_arrived") || F.getName().contains("publish") || F.getName().contains("requestOrder")){
                     if(!F.isDeclaration()){
                          {
                                        std::string format("arg_values: ");
                                        for (size_t i = 0; i < arg_values.size(); ++i) {
                                                format += " %s = %lu\n";
                                        }

                                        Value *str = builder.CreateGlobalStringPtr(format, "");
                                        std::vector<Value *> argsV({str});

                                        for (auto &v : arg_values) {
                                               // if(v != nullptr){
                                                        argsV.push_back(builder.CreateGlobalStringPtr(v->getName(), ""));
                                                        argsV.push_back(v);
                                               // }
                                        }
                                        builder.CreateCall(printfFunc, argsV, "calltmp");
                            }
                     }
          }
}

Here are the error, (note: I am printing everything before segmentation fault)

User:  main is calling _ZN2ft20TxtMqttFactoryClient23publishStationBroadcastENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdS6_S6_S6_l
_ZN2ft20TxtMqttFactoryClient23publishStationBroadcastENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdS6_S6_S6_l is called from this callInst  invoke void @_ZN2ft20TxtMqttFactoryClient23publishStationBroadcastENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdS6_S6_S6_l(%"class.ft::TxtMqttFactoryClient"* noundef nonnull align 4 dereferenceable(604) %788, %"class.std::__cxx11::basic_string"* noundef %59, double noundef %786, %"class.std::__cxx11::basic_string"* noundef %61, %"class.std::__cxx11::basic_string"* noundef %62, %"class.std::__cxx11::basic_string"* noundef %64, i32 noundef 60000)
          to label %803 unwind label %844, !dbg !29088


arguments:  _ZN2ft20TxtMqttFactoryClient23publishStationBroadcastENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdS6_S6_S6_l 
 _ZN2ft20TxtMqttFactoryClient23publishStationBroadcastENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdS6_S6_S6_l %"class.ft::TxtMqttFactoryClient"* %0
 _ZN2ft20TxtMqttFactoryClient23publishStationBroadcastENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdS6_S6_S6_l %"class.ft::TxtMqttFactoryClient"* %0%"class.std::__cxx11::basic_string"* %1
 _ZN2ft20TxtMqttFactoryClient23publishStationBroadcastENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdS6_S6_S6_l %"class.ft::TxtMqttFactoryClient"* %0%"class.std::__cxx11::basic_string"* %1double %2
 _ZN2ft20TxtMqttFactoryClient23publishStationBroadcastENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdS6_S6_S6_l %"class.ft::TxtMqttFactoryClient"* %0%"class.std::__cxx11::basic_string"* %1double %2%"class.std::__cxx11::basic_string"* %3
 _ZN2ft20TxtMqttFactoryClient23publishStationBroadcastENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdS6_S6_S6_l %"class.ft::TxtMqttFactoryClient"* %0%"class.std::__cxx11::basic_string"* %1double %2%"class.std::__cxx11::basic_string"* %3%"class.std::__cxx11::basic_string"* %4
 _ZN2ft20TxtMqttFactoryClient23publishStationBroadcastENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdS6_S6_S6_l %"class.ft::TxtMqttFactoryClient"* %0%"class.std::__cxx11::basic_string"* %1double %2%"class.std::__cxx11::basic_string"* %3%"class.std::__cxx11::basic_string"* %4%"class.std::__cxx11::basic_string"* %5
 _ZN2ft20TxtMqttFactoryClient23publishStationBroadcastENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdS6_S6_S6_l %"class.ft::TxtMqttFactoryClient"* %0%"class.std::__cxx11::basic_string"* %1double %2%"class.std::__cxx11::basic_string"* %3%"class.std::__cxx11::basic_string"* %4%"class.std::__cxx11::basic_string"* %5i32 %6
arg_values:   = 3204445520
  = 3204444448
  = 3889515023
Segmentation fault

I am pretty sure this is happening because of the accessing the values that doesn’t exit. But don’t know how to skip those. I tried to ignore accessing the values by checking if the value is null but didn’t work. As the arg_values is returning a list of arguments, I can’t check if the whole list is null (As there can be some values for an argument) and also can’t check the values while iterating. Then how can I skip those nullable values?

Your arguments don’t all look like longs to me. Once you’ve tried to print the first value that isn’t passed like a long (pointers are on x86-64, and the i32 is close enough, but the double goes in a floating-point register on x86-64) you’ll be out of sync and start reading the wrong registers (or stack locations) for the arguments, since you read an integer from an integer register or stack location but should have read a double from a floating-point register. This probably results in you reading a junk pointer that then gets interpreted as a pointer to a string and promptly crashes trying to print it.

This is pretty obnoxious.

1 Like

I am sorry for mentioning you and thanks for replying. As you said, i32 is close enough. As a result, I’m now reading the values as ints rather than unsigned longs. But I’m still getting the same error. I don’t understand why I am reading junk pointer now.

{
                                        std::string format("arg_values: ");
                                        for (size_t i = 0; i < arg_values.size(); ++i) {
                                                format += " %s = %d\n";
                                        }

                                        Value *str = builder.CreateGlobalStringPtr(format, "");
                                        std::vector<Value *> argsV({str});

                                        for (auto &v : arg_values) {
                                                //if(v != nullptr){
                                                        argsV.push_back(builder.CreateGlobalStringPtr(v->getName(), ""));
                                                        argsV.push_back(v);
                                                //}
                                        }
                                        builder.CreateCall(printfFunc, argsV, "calltmp");
                                }

There are some boolean values but as I am reading ints, so, all of those values should get converted into ints, right?

Because the i32, whilst inconsistent, wasn’t actually a problem for your specific ABI. The double was, and still is. It must be printed as a floating-point type, or converted to an integer type (whether FP-to-int or bitcast) if you insist on treating everything as if they are integers all of the same size.

Many thanks for your reply. But I still didn’t get it. I am adding a specifier according to the arguments of functions using this to create a global string of vectors that will store all the values each time the function is called,
format += " %s = %lu\n";
Then I am pushing the values retrieved from getName() according to the number of argument values,
argsV.push_back(builder.CreateGlobalStringPtr(v->getName(), ""));

You said,

> it must be printed as a floating-point type

Here, format += "%s = %lu\n";, this will get the values in unsigned long. But it should be printed using float, format += " %s = %f\n"; I didn’t understand how will I use bitcast in here, because BitCastInst (Value *S, Type *Ty, const Twine &NameStr=“”, Instruction *InsertBefore=nullptr) will convert the whole instruction not only the values after I get the instruction from the value instead of name v.getName()

or,

> converted to an integer type

Not exactly sure how to do this while creating space here, format += "%s = %d\n", are you saying I should convert it while getting the names using float2int,
argsV.push_back(builder.CreateGlobalStringPtr(float2intpass(v->getName()), ""));

Printing as a floating-point type and bitcasting are two alternatives, not to be done at the same time. You have three options:

  1. Look at v’s type and decide whether to use %(l)u or %f (and ideally also %p for pointers)
  2. Bitcast every value to an integer type (i.e. get its raw bits) so you can always use %(l)u (you should also extend things to be 64-bit but in practice it doesn’t matter for the ABI in use here)
  3. Convert floating-point values to integers with fptoui/fptosi instructions

This is the string that corresponds to %s. I’m not talking about changing this, this is fine and not the problem. The problem is that argsV.push_back(v); deals with values that aren’t just 64-bit integers (what %lu expects).

Do one or the other, not both.

I don’t understand this. BitCastInst creates a new instruction, yes. But the value is (normally) the instruction, there’s no distinction, instructions are just a type of value. And I don’t get what the issue with the name is here, I cannot understand what you mean.

No. Converting the name from a float to an int is utter nonsense. Convert v, the value, to an int.

Thank you so much, and I am so sorry for the stupid question last time. I am planning to use Bitcast so that I can use (%lu) always.

                              {
                                // using the format specifier for printing the values
                                        std::string format("arg_values: ");
                                        for (size_t i = 0; i < arg_values.size(); ++i) {
                                                format += " %s = %lu\n";
                                                //format += " %s = %f\n";
                                        }
                                // creating the string from format, then converting it into vector
                                        Value *str = builder.CreateGlobalStringPtr(format, "");
                                        std::vector<Value *> argsV({str});

                                        for (auto &v : arg_values) {
                                                argsV.push_back(builder.CreateGlobalStringPtr(v->getName(), ""));
                                                errs()<<"V Type: "<<*v->getType()<<"\n";
                                                //auto result = CastInst::Create(Instruction::SIToFP, v, FloatTyID, "", BB);
                                                auto res = builder.CreateBitCast(v, Type::getInt64Ty(context));
                                                errs()<<"Result Type: "<<*res->getType()<<"\n";
                                                errs()<<"res: "<<*res<<" v: "<< *v <<"\n";
                                                //argsV.push_back(v);
                                                argsV.push_back(res); //getting long values instead of usual type values to get rid of seg fault.
                                        }
                                        builder.CreateCall(printfFunc, argsV, "calltmp");
                                }

In here, I am able to cast the value to an unsigned long and it is compiling fine. But I couldn’t get the values as I was getting earlier. Here is the output of a demo file,

Provide 2 inputs => a,b.
If a is greater than 10 then subtract function will be called.
12
13

User:  main is calling _Z8subtracti
_Z8subtracti is called from this callInst  %15 = call noundef i32 @_Z8subtracti(i32 noundef %14), !dbg !36

a is greater than 10
arguments:  _Z8subtracti 
 _Z8subtracti i32 %0
arg_values:   = 0

If I push value argsV.push_back(v); instead of result argsV.push_back(res); then the arg_values will be the user input as following,

Provide 2 inputs => a,b.
If a is greater than 10 then subtract function will be called.
12
13

User:  main is calling _Z8subtracti
_Z8subtracti is called from this callInst  %15 = call noundef i32 @_Z8subtracti(i32 noundef %14), !dbg !36

a is greater than 10
arguments:  _Z8subtracti 
 _Z8subtracti i32 %0
arg_values:   = 12

I am guessing this is because I am inserting the bitcast instruction instead of value. But it worked fine till now, and suddenly I started getting this error, I didn’t change anything, not sure why I am getting this error. I have pasted the updated code above. Also, I don’t know how to get the value from bitcast instruction.

V Type: i32
Result Type: i64
res:   %4 = bitcast i32 %0 to i64 v: i32 %0
V Type: i32
Result Type: i64
res:   %5 = bitcast i32 %1 to i64 v: i32 %1
V Type: i32
Result Type: i64
res:   %3 = bitcast i32 %0 to i64 v: i32 %0
fatal error: error in backend: Cannot select: 0x1970a18: i64 = bitcast 0x19709b0
  0x19709b0: i32,ch = CopyFromReg 0x18f1078, Register:i32 %3
    0x1970948: i32 = Register %3
In function: _Z8subtractii
clang: error: clang frontend command failed with exit code 70 (use -v to see invocation)
Ubuntu clang version 14.0.6
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
clang: note: diagnostic msg: 
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang: note: diagnostic msg: /tmp/example-ae4f2e.cpp
clang: note: diagnostic msg: /tmp/example-ae4f2e.sh
clang: note: diagnostic msg: 

********************
Makefile:29: recipe for target 'ex' failed
make: *** [ex] Error 70

You can only bitcast between values of the same size (see LangRef); either convert your values to the right bit width and then bitcast to i64, or bitcast to iN (where N is the size of the value) and then convert to i64 (or just do the bitcast to iN step and rely on i32 being treated like i64 for variadic arguments in the x86-64 ABI).

This might be a stupid question again; please don’t mind. I need to create space at the beginning to call the print function, so I just put “unsigned long” in every space that will be filled in later.

You said I can only bitcast between values of the same size. So, what’s the point of converting unsigned long to unsigned long? Why do I need to convert the same type? Can you give me a reference to langref about this bitcasting values if the same size?

I don’t understand how do I convert the values to right bit width

Casting with the same size of the value, which is converting the values to the same type again, which can be done instead of getting the size like following,
auto res = builder.CreateBitCast(v,v->getType());
and then converting into i64, which is this one,
res = builder.CreateBitCast(res, Type::getInt64Ty(context));
What’s the point here, doing the same thing again, in this case, res is v?

What you meant by bitcast to iN step, if N is the size of the value, then I am casting it to the same type?

Because double is not an i64 yet both are 64-bit values, and your problem is you’re trying to print a double as if it were an i64 by using %lu.

1 Like

Ok, I don’t know how to convert your values to the right bit width. So, I tried to do the second step, which is bitcasting to iN (where N is the size of the value). But I thought casting it to the same type will solve the issue, so, I did the following,

                                        for (auto &v : arg_values) {
                                                argsV.push_back(builder.CreateGlobalStringPtr(v->getName(), ""));
                                                errs()<<"V Type: "<<*v->getType()<<"\n";
                                                //auto result = CastInst::Create(Instruction::SIToFP, v, FloatTyID, "", BB);
                                                //auto res = builder.CreateBitCast(v, Type::getInt64Ty(context));
                                                auto res = builder.CreateBitCast(v,v->getType());
                                                res = builder.CreateBitCast(res, Type::getInt64Ty(context));
                                                errs()<<"Result Type: "<<*res->getType()<<"\n";
                                                errs()<<"res: "<<*res<<" --v: "<< *v <<"\n";
                                                //argsV.push_back(v);
                                                argsV.push_back(res); //getting long values instead of usual type values to get rid of seg fault.
                                        }
                                        builder.CreateCall(printfFunc, argsV, "calltmp");

Which is casting it to the same type and then casting it to i64 but I don’t think this will solved the problem as it will convert double to i64 again. Can you briefly tell me, how to get the right bit width or how do I bitcast to iN? By “right bit width” did you mean, getting a bit width of 64 bit or, right bit width of the value? I guess value, if I am getting the bit width and then passing to the argsV(argument values), will it be changed to i32.

And what you meant by this “(or just do the bitcast to iN step and rely on i32 being treated like i64 for variadic arguments in the x86-64 ABI)” bitcasting a double to iN is still double right, then how bitcasting it to iN will give me i32 values. Is it the same as I thought, getting the bits and passing it to the argsV(argument values) will convert it into i32 bit.

Also, I am not using any double but while passing the result to the argsV, I am getting this error, is it because I am not getting the right bit width? => Sorry actually I am using double like the unsigned long is reading the values as a long int. So, I guess the following problem will be solved if I can convert the bits into right bit width.

fatal error: error in backend: Cannot select: 0x1a33ad8: i64 = bitcast 0x1a33a70
  0x1a33a70: i32,ch = CopyFromReg 0x19b4078, Register:i32 %3
    0x1a33a08: i32 = Register %3
In function: _Z8subtractii
clang: error: clang frontend command failed with exit code 70 (use -v to see invocation)
Ubuntu clang version 14.0.6
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
clang: note: diagnostic msg: 
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang: note: diagnostic msg: /tmp/example-81ab01.cpp
clang: note: diagnostic msg: /tmp/example-81ab01.sh
clang: note: diagnostic msg: 

********************
Makefile:29: recipe for target 'ex' failed
make: *** [ex] Error 70

Look at IRBuilder’s getIntNTy and CreateSExtOrTrunc.

1 Like
for (auto &v : arg_values) {
        argsV.push_back(builder.CreateGlobalStringPtr(v->getName(), ""));
        errs()<<"V Type: "<<*v->getType()<<"\n";
        //auto result = CastInst::Create(Instruction::SIToFP, v, FloatTyID, "", BB);
        //auto res = builder.CreateBitCast(v, Type::getInt64Ty(context));
// Target type is 64 bit and source type is value type
        Type *SourceTy = v->getType();
        Type *TargetTy = Type::getInt64Ty(context);
// Getting bit width of both source and target to convert it into the correct bit width
        unsigned TargetBitWidth = TargetTy->getIntegerBitWidth(); 
        unsigned SourceBitWidth = cast<IntegerType>(SourceTy)->getBitWidth(); 
// Getting the common bits between target and source
        //Type* common_bits = builder.getIntNTy(context,SourceBitWidth);
// Getting the bits and converting it to value
        IntegerType *IntPtrTy = builder.getIntNTy(SourceBitWidth);
        Constant *bits = Constant::getIntegerValue( IntPtrTy, APInt(IntPtrTy->getBitWidth(),0));
        //ConstantInt *bits = ConstantInt::get(context, common_bits);
        //errs()<<"common bits: "<<common_bits<<"\n";
        
        //auto res = builder.CreateBitCast(v,v->getType());
        //auto res = builder.CreateBitCast(MaxConstant ,v->getType());
        //res = builder.CreateBitCast(res, Type::getInt64Ty(context));
        //Value *Ovf = builder.CreateICmpSLT(v, MaxConstant, "Ovf");
        
        errs()<<"In CreateSExtOrTrunc\n";
        Value *result = builder.CreateSExtOrTrunc(bits, TargetTy);
        auto res = builder.CreateBitCast(result ,Type::getInt64Ty(context));

        errs()<<"Result Type: "<<*res->getType()<<"\n";
        errs()<<"**res: "<<*res<<" **v: "<< *v <<"\n";
        //argsV.push_back(v);
        argsV.push_back(res); //getting long values instead of usual type values to get rid of seg fault.
}
builder.CreateCall(printfFunc, argsV, "calltmp");

I didn’t find any viable conversion from type to value while I was getting the type from getIntNTy(). That’s why, I am getting N as an integer type because while converting it to value then I can use getIntegerValue(Type, APInt constant).

IntegerType *IntPtrTy = builder.getIntNTy(SourceBitWidth);
Constant *bits = Constant::getIntegerValue( IntPtrTy, APInt(IntPtrTy->getBitWidth(),0));

Passing the value generated with N size to the CreateSExtOrTrunc with the target type,

Value *result = builder.CreateSExtOrTrunc(bits, TargetTy);
auto res = builder.CreateBitCast(result ,Type::getInt64Ty(context));

But I am not getting the expected result for the demo code, the arg_values should be 13,

Provide 2 inputs => a,b.
If a is greater than 10 then subtract function will be called.
13
14

User:  main is calling _Z8subtracti
_Z8subtracti is called from this callInst  %15 = call noundef i32 @_Z8subtracti(i32 noundef %14), !dbg !36

a is greater than 10
arguments:  _Z8subtracti 
 _Z8subtracti i32 %0
arg_values:   = 0

Again, if I just pass value instead of bits to the CreateSExtOrTrunc() then it works fine for the demo code and getting the perfect value given, the code is following,

 Value *result = builder.CreateSExtOrTrunc(v, TargetTy); 

The output for using this code is following,

Provide 2 inputs => a,b.
If a is greater than 10 then subtract function will be called.
13
14

User:  main is calling _Z8subtracti
_Z8subtracti is called from this callInst  %15 = call noundef i32 @_Z8subtracti(i32 noundef %14), !dbg !36

a is greater than 10
arguments:  _Z8subtracti 
 _Z8subtracti i32 %0
arg_values:   = 13

But I think I should bitcast it to iN first and then convert it into 64 bit. I converted it but I am not getting the expected value.

The whole point is to handle types that aren’t integers, so cast is going to be totally broken there (I’m surprised you don’t see assertion failures, but maybe you have a build without assertions, in which case you’ll be getting junk for getBitWidth). You want to do something like ask DataLayout::getTypeSizeInBits.

for (auto &v : arg_values) {
        argsV.push_back(builder.CreateGlobalStringPtr(v->getName(), ""));
        errs()<<"V Type: "<<*v->getType()<<"\n";
        //auto result = CastInst::Create(Instruction::SIToFP, v, FloatTyID, "", BB);
        //auto res = builder.CreateBitCast(v, Type::getInt64Ty(context));
// Target type is 64 bit and source type is value type
        Type *SourceTy = v->getType();
        Type *TargetTy = Type::getInt64Ty(context);
// Getting bit width of both source and target to convert it into the correct bit width
        //unsigned TargetBitWidth = TargetTy->getIntegerBitWidth(); 
        //unsigned SourceBitWidth = cast<IntegerType>(SourceTy)->getBitWidth(); 
        const DataLayout &DL = M.getDataLayout();
        unsigned TargetBitWidth = DL.getTypeSizeInBits(TargetTy);
        unsigned SourceBitWidth = DL.getTypeSizeInBits(SourceTy);
        //unsigned TargetBitWidth = DL.getTypeSizeInBits(TargetTy).getFixedValue();
        //unsigned SourceBitWidth = DL.getTypeSizeInBits(SourceTy).getFixedValue();
// Getting the common bits between target and source
        //Type* common_bits = builder.getIntNTy(context,SourceBitWidth);
// Getting the Integer bits and converting it to value
        IntegerType *IntPtrTy = builder.getIntNTy(SourceBitWidth);
        //assert((*IntPtrTy)>0);
        //Constant *bits = Constant::getIntegerValue( IntPtrTy, APInt(IntPtrTy->getBitWidth(),0));
        Constant *bits = Constant::getIntegerValue( IntPtrTy, APInt(DL.getTypeSizeInBits(TargetTy),0));
        errs()<<"IntPtrTy: "<<*IntPtrTy<<" bits: "<<*bits<<"\n";
        //assert((*bits)>0);
        //static_assert(*bits == *(Constant::getIntegerValue( IntPtrTy, APInt(IntPtrTy->getBitWidth(),0))), "Bits should be a value");
        //ConstantInt *bits = ConstantInt::get(context, common_bits);
        //auto res = builder.CreateBitCast(v,v->getType());
        //auto res = builder.CreateBitCast(MaxConstant ,v->getType());
        //res = builder.CreateBitCast(res, Type::getInt64Ty(context));
        //Value *Ovf = builder.CreateICmpSLT(v, MaxConstant, "Ovf");

        errs()<<"In CreateSExtOrTrunc\n";
        Value *result = builder.CreateSExtOrTrunc(bits, TargetTy);
        auto res = builder.CreateBitCast(result ,Type::getInt64Ty(context));

        errs()<<"Result Type: "<<*res->getType()<<"\n";
        errs()<<"**res: "<<*res<<" **v: "<< *v <<"\n";
        //argsV.push_back(v);
        argsV.push_back(res); //getting long values instead of usual type values to get rid of seg fault.
}
builder.CreateCall(printfFunc, argsV, "calltmp");

Getting the type size in bits from the data layout, which accepts type as a parameter,

const DataLayout &DL = M.getDataLayout();
unsigned TargetBitWidth = DL.getTypeSizeInBits(TargetTy);
unsigned SourceBitWidth = DL.getTypeSizeInBits(SourceTy);

Then get the N bits and converting it to a value. After that, create bit cast. But still not getting the value. Still not the expected result. I also tried asserting, but I’m not sure why it’s not working, simply checking some values for assertions.

So you’re trying to print zeros, not v. In fact, other than writing v to errs, the only things you’re using v for are to get the name and type, which is clearly not going to generate code to pass v, converted or otherwise, to the function.

Thanks, the APInt() is taking the value but the 2nd parameter of APInt is uint64_t. I am creating bitcast to get the 64 value of this and getting error because I was not converting it. So, how do I pass it to the APInt() as a 2nd parameter.

Constant *bits = Constant::getIntegerValue( IntPtrTy, APInt(DL.getTypeSizeInBits(TargetTy),v);

Now, passing it like this. If I run this then getting this error,

clang++-14 -o example.ll -S -emit-llvm example.cpp
clang++-14 -I/usr/lib/llvm-14/include -std=c++14   -fno-exceptions -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Wl,-znodelete -fno-rtti -fpic -O3 -funroll-loops -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -DVERSION=1  -Wno-variadic-macros -g -shared valueMsgPub.cpp -o instrument.so
valueMsgPub.cpp:342:61: error: no matching constructor for initialization of 'llvm::APInt'
                                                Constant *bits = Constant::getIntegerValue( IntPtrTy, APInt(DL.getTypeSizeInBits(TargetTy),v);
                                                                                                      ^     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/llvm-14/include/llvm/ADT/APInt.h:108:3: note: candidate constructor not viable: no known conversion from 'llvm::Value *' to 'uint64_t' (aka 'unsigned long') for 2nd argument
  APInt(unsigned numBits, uint64_t val, bool isSigned = false)
  ^
/usr/lib/llvm-14/include/llvm/ADT/APInt.h:125:3: note: candidate constructor not viable: no known conversion from 'llvm::Value *' to 'ArrayRef<uint64_t>' (aka 'ArrayRef<unsigned long>') for 2nd argument
  APInt(unsigned numBits, ArrayRef<uint64_t> bigVal);
  ^
/usr/lib/llvm-14/include/llvm/ADT/APInt.h:1831:3: note: candidate constructor not viable: no known conversion from 'llvm::TypeSize' to 'uint64_t *' (aka 'unsigned long *') for 1st argument
  APInt(uint64_t *val, unsigned bits) : BitWidth(bits) { U.pVal = val; }
  ^
/usr/lib/llvm-14/include/llvm/ADT/APInt.h:153:3: note: candidate constructor not viable: requires single argument 'that', but 2 arguments were provided
  APInt(const APInt &that) : BitWidth(that.BitWidth) {
  ^
/usr/lib/llvm-14/include/llvm/ADT/APInt.h:161:3: note: candidate constructor not viable: requires single argument 'that', but 2 arguments were provided
  APInt(APInt &&that) : BitWidth(that.BitWidth) {
  ^
/usr/lib/llvm-14/include/llvm/ADT/APInt.h:134:3: note: candidate constructor not viable: requires 3 arguments, but 2 were provided
  APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
  ^
/usr/lib/llvm-14/include/llvm/ADT/APInt.h:147:3: note: candidate constructor not viable: requires 3 arguments, but 2 were provided
  APInt(unsigned numBits, StringRef str, uint8_t radix);
  ^
/usr/lib/llvm-14/include/llvm/ADT/APInt.h:150:12: note: candidate constructor not viable: requires 0 arguments, but 2 were provided
  explicit APInt() : BitWidth(1) { U.VAL = 0; }
           ^
valueMsgPub.cpp:342:100: error: expected ')'
                                                Constant *bits = Constant::getIntegerValue( IntPtrTy, APInt(DL.getTypeSizeInBits(TargetTy),v);
                                                                                                                                             ^
valueMsgPub.cpp:342:49: note: to match this '('
                                                Constant *bits = Constant::getIntegerValue( IntPtrTy, APInt(DL.getTypeSizeInBits(TargetTy),v);
                                                                                          ^
2 errors generated.

You don’t. APInt is for known compile-time constants. You shouldn’t be trying to construct a ConstantInt at all, I don’t know where all that came from in the first place. Just take v, pass it to CreateBitCast and pass that to CreateSExtOrTrunc.

I did the same earlier and I got the correct value for a demo file but for my project code, I was getting this following error,

In CreateSExtOrTrunc
clang++-14: /usr/lib/llvm-14/include/llvm/IR/IRBuilder.h:1911: llvm::Value *llvm::IRBuilderBase::CreateSExtOrTrunc(llvm::Value *, llvm::Type *, const llvm::Twine &): Assertion `V->getType()->isIntOrIntVectorTy() && DestTy->isIntOrIntVectorTy() && "Can only sign extend/truncate integers!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: clang++-14 --target=arm-linux-gnueabihf -flegacy-pass-manager -g -Xclang -load -Xclang /home/u18new/LLVM_PASSES/LogPasses-new/messagePublishFunc/instrument.so -std=gnu++0x -std=c++0x -DDEBUG -DSPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_TRACE -ITxtSmartFactoryLib/include -ITxtSmartFactoryLib/libs -I/home/ubuntu-18/Desktop/paho.mqtt.c/build/_install/include/ -I/home/ubuntu-18/Desktop/paho.mqtt.cpp/build/_install/include/ -Ideps/include -O0 -g3 -Wall -c -fmessage-length=0 -Wno-psabi -fPIC -MMD -MP -MFTxtSmartFactoryLib/Posix_Debug/src/TxtPanTiltUnit.d -MTTxtSmartFactoryLib/Posix_Debug/src/TxtPanTiltUnit.o -o TxtSmartFactoryLib/Posix_Debug/src/TxtPanTiltUnit.o TxtSmartFactoryLib/src/TxtPanTiltUnit.cpp
1.	<eof> parser at end of file
2.	Per-module optimization passes
3.	Running pass 'AFLCoverage Pass' on module 'TxtSmartFactoryLib/src/TxtPanTiltUnit.cpp'.
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
/usr/lib/x86_64-linux-gnu/libLLVM-14.so.1(_ZN4llvm3sys15PrintStackTraceERNS_11raw_ostreamEi+0x31)[0x7fe8eca6f6a1]
/usr/lib/x86_64-linux-gnu/libLLVM-14.so.1(_ZN4llvm3sys17RunSignalHandlersEv+0xee)[0x7fe8eca6d3ee]
/usr/lib/x86_64-linux-gnu/libLLVM-14.so.1(_ZN4llvm3sys15CleanupOnSignalEm+0x100)[0x7fe8eca6ea60]
/usr/lib/x86_64-linux-gnu/libLLVM-14.so.1(+0xd7a1bf)[0x7fe8ec99b1bf]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x12980)[0x7fe8f5d45980]
/lib/x86_64-linux-gnu/libc.so.6(gsignal+0xc7)[0x7fe8eaeabe87]
/lib/x86_64-linux-gnu/libc.so.6(abort+0x141)[0x7fe8eaead7f1]
/lib/x86_64-linux-gnu/libc.so.6(+0x303fa)[0x7fe8eae9d3fa]
/lib/x86_64-linux-gnu/libc.so.6(+0x30472)[0x7fe8eae9d472]
/home/u18new/LLVM_PASSES/LogPasses-new/messagePublishFunc/instrument.so(+0x5ca4)[0x7fe8e7a8eca4]
/usr/lib/x86_64-linux-gnu/libLLVM-14.so.1(_ZN4llvm6legacy15PassManagerImpl3runERNS_6ModuleE+0x946)[0x7fe8ecbaa7c6]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZN5clang17EmitBackendOutputERNS_17DiagnosticsEngineERKNS_19HeaderSearchOptionsERKNS_14CodeGenOptionsERKNS_13TargetOptionsERKNS_11LangOptionsEN4llvm9StringRefEPNSE_6ModuleENS_13BackendActionESt10unique_ptrINSE_17raw_pwrite_streamESt14default_deleteISK_EE+0x340b)[0x7fe8f3da069b]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(+0x1b89c01)[0x7fe8f40c4c01]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZN5clang8ParseASTERNS_4SemaEbb+0x244)[0x7fe8f2f40054]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZN5clang13CodeGenAction13ExecuteActionEv+0xb1)[0x7fe8f40c0f51]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZN5clang14FrontendAction7ExecuteEv+0x67)[0x7fe8f4a62727]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZN5clang16CompilerInstance13ExecuteActionERNS_14FrontendActionE+0x336)[0x7fe8f49b9d86]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZN5clang25ExecuteCompilerInvocationEPNS_16CompilerInstanceE+0x29b)[0x7fe8f4adbe8b]
clang++-14(_Z8cc1_mainN4llvm8ArrayRefIPKcEES2_Pv+0x98f)[0x41329f]
clang++-14[0x4114dc]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(+0x20fc392)[0x7fe8f4637392]
/usr/lib/x86_64-linux-gnu/libLLVM-14.so.1(_ZN4llvm20CrashRecoveryContext9RunSafelyENS_12function_refIFvvEEE+0xdd)[0x7fe8ec99af2d]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZNK5clang6driver10CC1Command7ExecuteEN4llvm8ArrayRefINS2_8OptionalINS2_9StringRefEEEEEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPb+0x140)[0x7fe8f4636e80]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZNK5clang6driver11Compilation14ExecuteCommandERKNS0_7CommandERPS3_+0x3f3)[0x7fe8f45fe693]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZNK5clang6driver11Compilation11ExecuteJobsERKNS0_7JobListERN4llvm15SmallVectorImplISt4pairIiPKNS0_7CommandEEEE+0x8a)[0x7fe8f45fe91a]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZN5clang6driver6Driver18ExecuteCompilationERNS0_11CompilationERN4llvm15SmallVectorImplISt4pairIiPKNS0_7CommandEEEE+0x1a7)[0x7fe8f4618407]
clang++-14(main+0x2816)[0x410f46]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x7fe8eae8ec87]
clang++-14(_start+0x2a)[0x40e3da]
clang: error: clang frontend command failed with exit code 134 (use -v to see invocation)
Ubuntu clang version 14.0.6
Target: arm-unknown-linux-gnueabihf
Thread model: posix
InstalledDir: /usr/bin
clang: note: diagnostic msg: 
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang: note: diagnostic msg: /tmp/TxtPanTiltUnit-440037.cpp
clang: note: diagnostic msg: /tmp/TxtPanTiltUnit-440037.sh
clang: note: diagnostic msg: 

********************
Makefile:128: recipe for target 'TxtSmartFactoryLib/Posix_Debug/src/TxtPanTiltUnit.o' failed
make: *** [TxtSmartFactoryLib/Posix_Debug/src/TxtPanTiltUnit.o] Error 134

For this piece of code,

for (auto &v : arg_values) {
        argsV.push_back(builder.CreateGlobalStringPtr(v->getName(), ""));
        errs()<<"V Type: "<<*v->getType()<<"\n";
        //auto result = CastInst::Create(Instruction::SIToFP, v, FloatTyID, "", BB);
        //auto res = builder.CreateBitCast(v, Type::getInt64Ty(context));
// Target type is 64 bit and source type is value type
        Type *SourceTy = v->getType();
        Type *TargetTy = Type::getInt64Ty(context);
// Getting bit width of both source and target to convert it into the correct bit width
        //unsigned TargetBitWidth = TargetTy->getIntegerBitWidth(); 
        //unsigned SourceBitWidth = cast<IntegerType>(SourceTy)->getBitWidth(); 
        const DataLayout &DL = M.getDataLayout();
        unsigned TargetBitWidth = DL.getTypeSizeInBits(TargetTy);
        unsigned SourceBitWidth = DL.getTypeSizeInBits(SourceTy);
        //unsigned TargetBitWidth = DL.getTypeSizeInBits(TargetTy).getFixedValue();
        //unsigned SourceBitWidth = DL.getTypeSizeInBits(SourceTy).getFixedValue();
// Getting the common bits between target and source
        //Type* common_bits = builder.getIntNTy(context,SourceBitWidth);
// Getting the Integer bits and converting it to value
        IntegerType *IntPtrTy = builder.getIntNTy(SourceBitWidth);
        //assert((*IntPtrTy)>0);
        //Constant *bits = Constant::getIntegerValue( IntPtrTy, APInt(IntPtrTy->getBitWidth(),0));
        //Constant *bits = Constant::getIntegerValue( IntPtrTy, APInt(DL.getTypeSizeInBits(TargetTy),ArrayRef<uint64_t>(v));
        //errs()<<"IntPtrTy: "<<*IntPtrTy<<" bits: "<<*bits<<"\n";
        //assert((*bits)>0);
        //static_assert(std::is_integral<Constant>(), "T must be integral");
        //static_assert(*bits == *(Constant::getIntegerValue( IntPtrTy, APInt(IntPtrTy->getBitWidth(),0))), "Bits should be a value");
        //ConstantInt *bits = ConstantInt::get(context, common_bits);
        //auto res = builder.CreateBitCast(v,v->getType());
        //auto res = builder.CreateBitCast(MaxConstant ,v->getType());
        //res = builder.CreateBitCast(res, Type::getInt64Ty(context));
        //Value *Ovf = builder.CreateICmpSLT(v, MaxConstant, "Ovf");

        errs()<<"In CreateSExtOrTrunc\n";
        Value *result = builder.CreateSExtOrTrunc(v, TargetTy);
        auto res = builder.CreateBitCast(result ,Type::getInt64Ty(context));

        errs()<<"Result Type: "<<*res->getType()<<"\n";
        errs()<<"**res: "<<*res<<" **v: "<< *v <<"\n";
        //argsV.push_back(v);
        argsV.push_back(res); //getting long values instead of usual type values to get rid of seg fault.
}

I thought this is because I was not casting the value properly but I might be wrong. The problem can be because of something else. I ain’t sure if it’s a null pointer problem or, not.

This is what I said. You did it the other way round. That is why it doesn’t work.