[cfe-dev] FullSourceLoc, getSpellingLineNumber segmentation fault

victor via cfe-dev cfe-dev at lists.llvm.org
Wed Mar 2 09:11:41 PST 2016


OMG. After long hours trying to figure out what was going on, I applied my system to other C++ programs and the system worked perfectly. So, once I knew that the problem was in the C++ program I was using to check my system:

1) I decided to create a new application from scratch with the minimum. This new application worked when I run it in the C++ program. 

2) I did the contrary: starting from the complete application, I was removing method by method invokation to know which part was the responsible to make the system crash. However, I didn't manage to get it work. 

Finally, looking at the Makefile of the C++ program, I found that in the rule to generate the object file of the program, there was the -DDEBUG flag. So I provided this flag after "--" when running my application. That worked!! 

Now, I have two doubts:
1) I don't know why the application that I started from scratched worked even without incluiding -DDEBUG and the one that I was skimming derived from the complete application did not. What could be affecting in my system to make this difference?

2) Should then I use FullSourceLoc or PresumedLoc in the end?

Thank you for your time Mikhail. 


From: mikhail.ramalho at gmail.com
Date: Wed, 2 Mar 2016 13:35:28 +0000
Subject: Re: [cfe-dev] FullSourceLoc, getSpellingLineNumber segmentation fault
To: pedretti_86 at hotmail.com
CC: cfe-dev at lists.llvm.org

I'm sorry to hear that it didn't help.
My last advice would be to update to clang 3.7 (or 3.8, when it's released). I know that this can create a whole new set of problems but it's the only possible solution I can find.
Since I moved to 3.8, clang has been a lot more stable.
Thank you,
2016-03-02 13:21 GMT+00:00 victor <pedretti_86 at hotmail.com>:






Thank you very much. Bad news, Mikhail. I tried your fix and it doesn't work by the moment.  The problem is in this line:

PresumedLoc PLoc = sm.getPresumedLoc(SpellingLoc)
(note: the compiler gave me an error when I put PresumedLoc& PLoc, so I just delete &). 

Just to discard that other things could be causing the problem, I have attempted the following:

* I don't call to HandleTranslationUnit before doing this, so the AST is not traversed twice. 

* Instead of taking a MemberExpr, I have tried with a Stmt and a CXXMethodDecl. The same. However, taking the CXXRecordDecl that nested the statement and the method does worked. 

* I have tried to assign the ASTContext as in the ASTDumper:

ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
This was even worse. Failed directly in:
SourceLocation SpellingLoc = sm.getSpellingLoc(FS->getSourceRange().getBegin());

Anyway, I'm using ASTMatchers, so I update the ASTContext in each match:

void System::run(const MatchFinder::MatchResult &Result) {
    Context = Result.Context; (Context is a field of the class System declared as ASTContext *Context;)
    ...
}

* I have also tried to check that the object "SpellingLoc" wasn't invalid:

if(SpellingLoc.isValid()){
      PresumedLoc PLoc = sm.getPresumedLoc(SpellingLoc);
}

The SpellingLoc object , however, is valid.

Sincerely, I don't know what else to try.  This is the code as I have it right now:

void System::run(const MatchFinder::MatchResult &Result) {
    Context = Result.Context; 

    const Stmt *FS = 0;
    if( FS =  Result.Nodes.getNodeAs<clang::Stmt>("statement")){

       ...

       SourceManager& sm = Context->getSourceManager();
       SourceLocation SpellingLoc = sm.getSpellingLoc(FS->getSourceRange().getBegin());

       if(SpellingLoc.isValid()){
           PresumedLoc PLoc = sm.getPresumedLoc(SpellingLoc);

           if (!PLoc.isInvalid()) {
               std::pair<unsigned, const char *> location = 
                       std::pair<unsigned, const char *>(PLoc.getLine(), PLoc.getFilename());
                       
               getCoverage(location);    
           }
       }
    }
}

Perhaps something in the code of the program that I'm using to check this impedes the correct generation of the AST...


From: mikhail.ramalho at gmail.com
Date: Tue, 1 Mar 2016 17:45:15 +0000
Subject: Re: [cfe-dev] FullSourceLoc, getSpellingLineNumber segmentation fault
To: pedretti_86 at hotmail.com
CC: cfe-dev at lists.llvm.org

Hello,
I finally found the two commits the "fixed"  the crashes, the first one might help you:
1. Use PresumedLoc instead of FullSourceLoc
Basically, it's the code used in ASTDumper. 
I have something like:
  sm = &ASTContext->getSourceManager();
  if(!sm)    return;
  clang::SourceLocation SpellingLoc = sm->getSpellingLoc(decl.getSourceRange().getBegin());  clang::PresumedLoc &PLoc = sm->getPresumedLoc(SpellingLoc);
  if (PLoc.isInvalid()) {    location.set_file("<invalid sloc>");    return;  }
  location.set_line(PLoc.getLine());  location.set_file(PLoc.getFilename());  

where:
sm is a clang::SourceManager *sm;ASTContext is a clang::ASTContext *ASTContext; location is an internal class that holds location information.
One minor note is to always update your ASTContext (in your case, the object Context), since it changes from translation unit. 

~
2. I was using virtual files, whose content was mapped into a local string, something like:
for(auto file : files){  std::string intrinsics = get_instrinsics();
  clang::tooling::ClangTool Tool(Compilations, sources);  Tool.mapVirtualFile("/esbmc_intrinsics.h", intrinsics);
  Tool.buildASTs(ASTs);
}
So I changed std::string to be a member of the class that calls this code.
~
Since you're not using virtual files, the second one shouldn't help, but try the first one and see if it fixes the problem.
I hope it helps.
Thank you,

2016-03-01 14:46 GMT+00:00 victor <pedretti_86 at hotmail.com>:



Oh sorry! Forget about the previous message. It is not working (I had commented the line where getSpellingLineNumber was called).  I definitely don't know how to sort out this issue. The problem is that the tool crashes when reaching that point: is there something I can do so that, at least, the tool doesn't crash? 

Thanks and sorry again.

From: mikhail.ramalho at gmail.com
Date: Mon, 29 Feb 2016 19:16:28 +0000
Subject: Re: [cfe-dev] FullSourceLoc, getSpellingLineNumber segmentation fault
To: pedretti_86 at hotmail.com
CC: cfe-dev at lists.llvm.org

Hi,
I used to face a lot of crashes on this method, it would usually explode at some #__SSE2__ code in a static method called ComputeLineNumbers inside clang.
Are you using virtual files? Are you generating the AST more than once (I mean, calling Tool.BuildAST() more than once)?
I don't quite remember how I fixed, but I _think_ those two might have something to do with the problem.
Cheers,

2016-02-29 18:22 GMT+00:00 victor via cfe-dev <cfe-dev at lists.llvm.org>:



Hi,

Does somebody know what can make the method getSpellingLineNumber from FullSourceLoc to generate a segmentation fault?  I'm using clang 3.6.

http://clang.llvm.org/doxygen/classclang_1_1FullSourceLoc.html#a52927fcf23cf662c209e5e996bf59917

Before using this method, I have checked that the FullSourceLoc is valid. This is the code:

 if(loc.isValid()){

 
         if(!(loc.getFileID().isInvalid())){
 
            if(Context->getSourceManager().getFileEntryForID(loc.getFileID()) != NULL){

                   unsigned int = loc.getSpellingLineNumber();
            }
         }
  }

I can't find anything special in the code which I'm using to check if my program works:

    void DeleteNode( XMLNode* node )    {
        node->_parent->DeleteChild( node );
    }

And this is the tree:

| | |-CXXMethodDecl 0x26b4090 <line:1576:5, line:1578:5> line:1576:10 DeleteNode 'void (class tinyxml2::XMLNode *)'
| | | |-ParmVarDecl 0x26b4010 <col:22, col:31> col:31 used node 'class tinyxml2::XMLNode *'
| | | |-CompoundStmt 0x26c9500 <col:38, line:1578:5>
| | | | `-CXXMemberCallExpr 0x26c94b8 <line:1577:9, col:42> 'void'
| | | |   |-MemberExpr 0x26c9460 <col:9, col:24> '<bound member function type>' ->DeleteChild 0x2699420
| | | |   | `-ImplicitCastExpr 0x26c9448 <col:9, col:15> 'class tinyxml2::XMLNode *' <LValueToRValue>
| | | |   |   `-MemberExpr 0x26c9418 <col:9, col:15> 'class tinyxml2::XMLNode *' lvalue ->_parent 0x269a310
| | | |   |     `-ImplicitCastExpr 0x26c9400 <col:9> 'class tinyxml2::XMLNode *' <LValueToRValue>
| | | |   |       `-DeclRefExpr 0x26c93d8 <col:9> 'class tinyxml2::XMLNode *' lvalue ParmVar 0x26b4010 'node' 'class tinyxml2::XMLNode *'

The object "loc" contains the location of the MemberExpr "_parent". 

Thanks.
 		 	   		  

_______________________________________________

cfe-dev mailing list

cfe-dev at lists.llvm.org

http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev




-- 

Mikhail Ramalho.
 		 	   		  


-- 

Mikhail Ramalho.void Mutation::run(const MatchFinder::MatchResult &Result) {void Mutation::run(const MatchFinder::MatchResult &Result) {void Mutation::run(const MatchFinder::MatchResult &Result) {

 		 	   		  


-- 

Mikhail Ramalho.
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160302/c1b3b841/attachment.html>


More information about the cfe-dev mailing list