<eof> parser at end of file

I am trying to get function arguments from a project code. At first, I tried to get arguments from a 1 function. It worked fine. I also tried to do the same for a couple of functions that has the word “publish” in them. It is dumping while using the pass to create an object of a particular file, “TxtSortingLineRun.cpp.” I have created the IR of that file and also checked if this file contains functions with publish word on it. There is a lot of functions like that, but clang is crashing at the end,
Here is the error that I am getting,

found:_ZN2ft20TxtMqttFactoryClient14publishSLD_AckENS_15TxtSldAckCode_tENS_11TxtWPType_tEil                                                                                                                 
  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.$
qtt.cpp/build/_install/include/ -Ideps/include -O0 -g3 -Wall -c -fmessage-length=0 -Wno-psabi -fPIC -MMD -MP -MFTxtSmartFactoryLib/Posix_Debug/src/TxtSortingLineRun.d -MTTxtSmartFactoryLib/Posix_Debug/sr$
/TxtSortingLineRun.o -o TxtSmartFactoryLib/Posix_Debug/src/TxtSortingLineRun.o TxtSmartFactoryLib/src/TxtSortingLineRun.cpp                                                                                 
1.      <eof> parser at end of file
2.      Per-module optimization passes
3.      Running pass 'AFLCoverage Pass' on module 'TxtSmartFactoryLib/src/TxtSortingLineRun.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)[0x7fa8481b76a1]
/usr/lib/x86_64-linux-gnu/libLLVM-14.so.1(_ZN4llvm3sys17RunSignalHandlersEv+0xee)[0x7fa8481b53ee]
/usr/lib/x86_64-linux-gnu/libLLVM-14.so.1(_ZN4llvm3sys15CleanupOnSignalEm+0x100)[0x7fa8481b6a60]
/usr/lib/x86_64-linux-gnu/libLLVM-14.so.1(+0xd7a1bf)[0x7fa8480e31bf]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x12980)[0x7fa85148d980]
/usr/lib/x86_64-linux-gnu/libLLVM-14.so.1(+0xe58ff6)[0x7fa8481c1ff6]
/usr/lib/x86_64-linux-gnu/libLLVM-14.so.1(_ZNK4llvm5Value5printERNS_11raw_ostreamERNS_17ModuleSlotTrackerEb+0x48a)[0x7fa8481c1e0a]
/usr/lib/x86_64-linux-gnu/libLLVM-14.so.1(_ZNK4llvm5Value5printERNS_11raw_ostreamEb+0xc9)[0x7fa8481c1879]
/home/u18new/LLVM_passes/LogPasses-new/messagePublishFunc/instrument.so(+0x2c58)[0x7fa8431d7c58]
/usr/lib/x86_64-linux-gnu/libLLVM-14.so.1(_ZN4llvm6legacy15PassManagerImpl3runERNS_6ModuleE+0x946)[0x7fa8482f27c6]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZN5clang17EmitBackendOutputERNS_17DiagnosticsEngineERKNS_19HeaderSearchOptionsERKNS_14CodeGenOptionsERKNS_13TargetOptionsERKNS_11LangOptionsEN4llvm9StringRef$
PNSE_6ModuleENS_13BackendActionESt10unique_ptrINSE_17raw_pwrite_streamESt14default_deleteISK_EE+0x340b)[0x7fa84f4e869b]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(+0x1b89c01)[0x7fa84f80cc01]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZN5clang8ParseASTERNS_4SemaEbb+0x244)[0x7fa84e688054]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZN5clang13CodeGenAction13ExecuteActionEv+0xb1)[0x7fa84f808f51]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZN5clang14FrontendAction7ExecuteEv+0x67)[0x7fa8501aa727]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZN5clang16CompilerInstance13ExecuteActionERNS_14FrontendActionE+0x336)[0x7fa850101d86]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZN5clang25ExecuteCompilerInvocationEPNS_16CompilerInstanceE+0x29b)[0x7fa850223e8b]
clang++-14(_Z8cc1_mainN4llvm8ArrayRefIPKcEES2_Pv+0x98f)[0x41329f]
clang++-14[0x4114dc]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(+0x20fc392)[0x7fa84fd7f392]
/usr/lib/x86_64-linux-gnu/libLLVM-14.so.1(_ZN4llvm20CrashRecoveryContext9RunSafelyENS_12function_refIFvvEEE+0xdd)[0x7fa8480e2f2d]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZNK5clang6driver10CC1Command7ExecuteEN4llvm8ArrayRefINS2_8OptionalINS2_9StringRefEEEEEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPb+0x140)[0x7fa84f$
7ee80]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZNK5clang6driver11Compilation14ExecuteCommandERKNS0_7CommandERPS3_+0x3f3)[0x7fa84fd46693]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZNK5clang6driver11Compilation11ExecuteJobsERKNS0_7JobListERN4llvm15SmallVectorImplISt4pairIiPKNS0_7CommandEEEE+0x8a)[0x7fa84fd4691a]
/usr/lib/x86_64-linux-gnu/libclang-cpp.so.14(_ZN5clang6driver6Driver18ExecuteCompilationERNS0_11CompilationERN4llvm15SmallVectorImplISt4pairIiPKNS0_7CommandEEEE+0x1a7)[0x7fa84fd60407]
clang++-14(main+0x2816)[0x410f46]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x7fa8465d6c87]
clang++-14(_start+0x2a)[0x40e3da]
clang: error: clang frontend command failed with exit code 139 (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/TxtSortingLineRun-966083.cpp
clang: note: diagnostic msg: /tmp/TxtSortingLineRun-966083.sh
clang: note: diagnostic msg:

********************
Makefile:129: recipe for target 'TxtSmartFactoryLib/Posix_Debug/src/TxtSortingLineRun.o' failed
make: *** [TxtSmartFactoryLib/Posix_Debug/src/TxtSortingLineRun.o] Error 139

In the pass I am just checking if there is any functions containing publish word on it, if it is present then injecting a print call,

if(F.getName().contains("message_arrived") || F.getName().contains("publish")){
                        Function* msg = &F;
                        if(msg != nullptr){
                                auto &BB = msg->getEntryBlock();
                                errs()<<BB<<"\n";
                                std::vector<std::string> arguments;
                                BasicBlock::iterator IP = BB.getFirstInsertionPt();
                                IRBuilder<> builder(&(*IP));
                                std::string format("\narguments: ");

                                std::string s;
                                raw_string_ostream rso(s);
                                rso << F.getName() << " ";
                                errs()<<"rso.str():"<<rso.str()<<"\n";
                                arguments.push_back(rso.str());
                                for(auto i = F.arg_begin();i!=F.arg_end();++i){
                                        rso << *i<<"\n";
                                        errs()<<"*i: "<<*i<<"\n";
                                        arguments.push_back(rso.str());
                                }
                                for (size_t i = 0; i < arguments.size(); ++i) {
                                        format += " %s\n";
                                }
                                Value *str = builder.CreateGlobalStringPtr(format, "");

                                std::vector<Value *> argsV({str});

                                for (auto &s : arguments) {
                                        argsV.push_back(builder.CreateGlobalStringPtr(s, ""));
                                }
                                builder.CreateCall(printfFunc, argsV, "calltmp");

@sylvestre @akorobeynikov @tobiashieta @smithp35 @tstellar @rpmvig @tedwoodward @jdoerfert, will appreciate any thoughts you have.

That’s not an error, that’s just telling you a bit about the current state.

As you can see from the function names here, you’re in a signal handler.

And these give you the exit code, 139, which is signal 11, SIGSEGV. Somewhere in there you presumably have a null pointer.

This is particularly strange code… F is a reference so by definition it’s not null, and you’ve also gone and called functions so you’re definitely not going to reach the if with msg being null. I also don’t see anything in your code that’s going to print out the "found:_ZN2ft20TxtMqttFactoryClient14publishSLD_AckENS_15TxtSldAckCode_tENS_11TxtWPType_tEil " shown in your output, which is probably useful to see given that’s the last thing known to have run…

Many thanks for your reply. I am sorry, I have removed the comments and then I mistakenly remove a errs() command, here is the full code,

                if(F.getName().contains("message_arrived") || F.getName().contains("publish")){
                //if(F.getName().contains("message_arrived") || F.getName().contains("_ZN2ft20TxtMqttFactoryClient14publishSLD_AckENS_15TxtSldAckCode_tENS_11TxtWPType_tEil")){
                //if(F.getName().contains("message_arrived")){
                        errs()<<"found:"<<F.getName()<<"\n";
                        Function* msg = &F;
                        if(msg != nullptr){
                                //errs()<<"Skipping the null called function\n";
                                //continue;


                                auto &BB = msg->getEntryBlock();
                                errs()<<BB<<"\n";
                                std::vector<std::string> arguments;
                                BasicBlock::iterator IP = BB.getFirstInsertionPt();
                                IRBuilder<> builder(&(*IP));

                                // The format string for the printf function, declared as a global literal
                                std::string format("\narguments: ");

                                std::string s;
                                raw_string_ostream rso(s);
                                rso << F.getName() << " ";
                                errs()<<"rso.str():"<<rso.str()<<"\n";
                                arguments.push_back(rso.str());
                                for(auto i = F.arg_begin();i!=F.arg_end();++i){
                                        errs()<<"\narguments: "<<*i<<"\n";
                                        //std::string s;
                                        //raw_string_ostream rso(s);
                                        rso << *i<<"\n";
                                        errs()<<"*i: "<<*i<<"\n";
                                        arguments.push_back(rso.str());
                                }
                                for (size_t i = 0; i < arguments.size(); ++i) {
                                        format += " %s\n";
                                }
                                Value *str = builder.CreateGlobalStringPtr(format, "");

                                std::vector<Value *> argsV({str});

                                for (auto &s : arguments) {
                                        argsV.push_back(builder.CreateGlobalStringPtr(s, ""));
                                }
                                builder.CreateCall(printfFunc, argsV, "calltmp");
                   }

It is returning with exit code 139, which means I have a null pointer but I am looking for null pointer and if found then not executing that piece of code,

                if(F.getName().contains("message_arrived") || F.getName().contains("publish")){
                //if(F.getName().contains("message_arrived") || F.getName().contains("_ZN2ft20TxtMqttFactoryClient14publishSLD_AckENS_15TxtSldAckCode_tENS_11TxtWPType_tEil")){
                //if(F.getName().contains("message_arrived")){
                        errs()<<"found:"<<F.getName()<<"\n";
                        Function* msg = &F;
                        if(msg != nullptr){
                                //errs()<<"Skipping the null called function\n";
                                //continue;

Also, you can see that the errs() is printing the "found:_ZN2ft20TxtMqttFactoryClient14publishSLD_AckENS_15TxtSldAckCode_tENS_11TxtWPType_tEil "
function.
This is the file: TxtSortingLineRun.cpp

assert(mqttclient);
mqttclient->publishSLD_Ack(SLD_SORTED, getDetectedColor(), lastColorValue, TIMEOUT_MS_PUBLISH);

While cross-compiling the whole project with the pass, this file caused clang to crash. In this file at line 309, you can see an explicit call is made to a publish function. It is using assert to test if the “mqttclient” is defined. It is defined here: ft::TxtMqttFactoryClient* mqttclient;
And this function publishSLD_Ack(...) is inheriting class TxtMqttFactoryClient as defined in here: void TxtMqttFactoryClient::publishSLD_Ack(…)

void TxtMqttFactoryClient::publishSLD_Ack(TxtSldAckCode_t code, TxtWPType_t type, int value, long timeout){
....
}

@jrtc27 will appreciate any suggestions you have.

I also printed the function to see when it was triggered. It is a nonnull function,

Makefile:132: recipe for target 'TxtSmartFactoryLib/Posix_Debug/src/TxtSortingLineRun.ll' failed                                                                                                            
make: *** [TxtSmartFactoryLib/Posix_Debug/src/TxtSortingLineRun.ll] Error 139                                                                                                                               
u18new@u18new-VirtualBox:~/txt_training_factory$                                                                                                                                                            
u18new@u18new-VirtualBox:~/txt_training_factory$ make TxtSmartFactoryLib/Posix_Debug/src/TxtSortingLineRun.ll                                                                                               
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 -D"DEBUG" -D"SPDLOG_A
CTIVE_LEVEL=SPDLOG_LEVEL_TRACE" -I"TxtSmartFactoryLib/include" -I"TxtSmartFactoryLib/libs" -I"/home/ubuntu-18/Desktop/paho.mqtt.c/build/_install/include/" -I"/home/ubuntu-18/Desktop/paho.mqtt.cpp/build/_i
nstall/include/" -I"deps/include" -O0 -g3 -Wall -c -fmessage-length=0 -Wno-psabi -emit-llvm -S -fPIC -MMD -MP -MF"TxtSmartFactoryLib/Posix_Debug/src/TxtSortingLineRun.ll" -MT"TxtSmartFactoryLib/Posix_Debu
g/src/TxtSortingLineRun.ll" -o "TxtSmartFactoryLib/Posix_Debug/src/TxtSortingLineRun.ll" TxtSmartFactoryLib/src/TxtSortingLineRun.cpp                                                                       
found:_ZN2ft20TxtMqttFactoryClient14publishSLD_AckENS_15TxtSldAckCode_tENS_11TxtWPType_tEil                                                                                                                 
After declaring msg                                                                                                                                                                                         
checking if it's nullptr:declare void @_ZN2ft20TxtMqttFactoryClient14publishSLD_AckENS_15TxtSldAckCode_tENS_11TxtWPType_tEil(%"class.ft::TxtMqttFactoryClient"* noundef nonnull align 4 dereferenceable(604)
, i32 noundef, i32 noundef, i32 noundef, i32 noundef) #1

I think the entry basic block I am getting from the function is returning null because that variable mqttclient is created in some other file and the function inherited TxtMqttFactoryClient which is present in some other file. But I don’t know how do I check if the basic block is returning null.

There are a lot of pointers involved in your code, not just msg, which isn’t null here. Given what gets printed, i.e. that no BB gets printed, and the link to the code you gave, your problem is that, whilst F/msg isn’t null, it’s for a declaration, not a definition, and so has no basic blocks in it (void foo(); vs void foo() { ... }), and thus getEntryBlock is what’s crashing.

I also don’t understand why you’re introducing msg = &F in the first place, just use F. in place of msg->, it’s needlessly confusing to have both.

To check if the function is returning nullptr, I declared the address of the function to msg. But thanks for pointing out the problem. How do I check if the basic block is returning null?

Yeah, the getEntryBlock is crashing but how do I check if it is null.

F is a reference. By definition references are not null. Any half-decent optimising C++ compiler will delete your null check as impossible.

Like I said, your problem is your code only works on definitions, not declarations, so check F.isDeclaration() is false.

It worked but why it worked when F.isDeclaration() is false. This is the updated code,

It worked but why it worked when F.isDeclaration() is false. My code looks like this now,

Function* msg = &F;
 errs()<<"After declaring msg\n";
 if(msg != nullptr && F.isDeclaration()==false){
     errs()<<"checking if it's nullptr:"<<*msg<<"\n";

Again, msg != nullptr is completely and utterly useless. It’s like saying *p = 1; if (p != nullptr), if you reach the if then it is too late to check whether msg is null, by definition it’s not, and if it was then you’ve already invoked UB and likely crashed. And the compiler will delete your check.

Also, x == false is bad code. Use !x.

It works for the reason I said. Declarations do not have basic blocks in them. Therefore if you want to get the basic blocks of a function you must ensure it’s not a declaration.

Many thanks for your reply and help.

Many thanks for helping to solve this problem. I was able to inject a print inside the message_arrrived and publish function using following code,

if(F.getName().contains("message_arrived") || F.getName().contains("publish")){
     if(!F.isDeclaration()){
         .......
     }

Suppose, initially I have this function,

void message_arrived(p1,p2,p3){
    .....
}

Now after I inject the print, then it becomes,

void message_arrived(p1,p2,p3){
   printf(p1,p2,p3);
   .....
}

Now, I want to add another print from where that function is called. As this is called from here,

main(){
     message_arrived(p1,p2,p3);
}

I want to add print in this function,

main(){
     print("calling message_arrived function from main");
     message_arrived(p1,p2,p3);
}

I am iterating over the functions; after I get the message_arrived function, can I get the CallInst that calls this function or the BasicBlock from where that function is called?
OR,
Do I need to go through each BasicBlock and check if there is a call instruction calling these two functions and injecting print there?

A Function is a Value so Value::uses() and similar functions are available.

Many thanks for your reply. By similar functions did you mean getCallInst or, getBasicBlock. I don’t see any member function to get callInst or, BasicBlock in classllvm_1_1Value.html. There is only one function which is a boolean to check if BasicBlock is used. But it takes a BasicBlock as an argument. But there is no member function to get the basic block.

bool 	isUsedInBasicBlock (const BasicBlock *BB) 

I can get the value Id but from it but can’t use it to get the value name or anything,

unsigned vid = F.getValueID();
errs()<<"vid: "<<vid<<"\n";
//errs()<<"Name: "<<vid.getName()<<"\n"; // will not work

Again, if I want to get value name from function, I can get it, it will not show any error though there is no member function in classllvm_1_1Function.html to get the value name. But with this, I will only get the address. I can’t get the name

ValueName* vName = F.getValueName();
errs()<<"Value Name: "<<vName<<"\n";
//errs()<<"Value Name: "<<*vName<<"\n"; // shows error

And the following code will not work for both value id and value name as I don’t have the basic block to pass as a parameter.

//errs()<<"Basic Block: "<<vName->isUsedInBasicBlock()<<"\n"; // not work

Can you please explain a little bit more about the similar functions you mentioned specifically, how can I get the BasicBlock from where that function is called?

Like I said, look at llvm::Value::uses(), which Function inherits. It’ll give you every Use, which has a getUser method that’ll get you the Instruction or Constant using the Function.

1 Like

Many thanks for replying. But I really need to know something. This might be a weird question. Sorry about that, I need to understand. To get the user, I can use the getUser defined in llvm/Use.h. This use is the edge between the value definition and its users. User is inheriting value, and function is inheriting user as a grandchild. So, function is a grandchild of both value and user.
The use.h file, which is a linked list, supports jumping directly to the used value when we arrive from the user’s operands, and jumping directly to the user when we arrive from the value’s uses.
So, I can get 1 user from the value of the function directly as it says I can jump to the user’s operands when we arrive from the value’s uses. Which means this should work,

auto vName = F.getName();
errs()<<"ValueName: "<<vName<<"\n";
errs()<<"users: "<<vName.getUser()<<"\n";

But this is returning a stringRef and getValueID is returning a unsigned int. And both of those don’t have getUser defined in them.
Ok, even if it is not working I should be able to iterate over the users like following,

for(auto ui = user_begin();ui!=user_end();++i){
   errs()<<"Users: "<<ui.getUser()<<"\n";
}

In this case, I’m not sure where I went wrong.

Why are you trying to call getUser on a StringRef? Look at the Function object.

Yeah, those are two different pieces of code. The following code is not working, I understand the reason,

auto vName = F.getName();
errs()<<"ValueName: "<<vName<<"\n";
errs()<<"users: "<<vName.getUser()<<"\n";

But I can’t even iterate users,

for(auto ui = inst.user_begin();ui!=inst.user_end();++i){
   errs()<<"Users: "<<ui.getUser()<<"\n";
}

I think I need to use the instruction to get the user, but which instruction should I use? If it is the callInst, then I have to get the called function.