-
Notifications
You must be signed in to change notification settings - Fork 482
WIP: Baseline which can run big programs #1789
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
I think you could continue to narrow down the usage of OPtions::HandleREcur(). I mean maybe you could put the option check inside the function.
For example,
"// Check if this recursive call should be skipped
if (shouldSkipRecursiveCall(callNode, funObjVar))
{
// In TOP mode, set return value and stores to TOP
// In WIDEN\_ONLY/WIDEN\_NARROW, just skip (WTO handles it)
if (Options::HandleRecur() == TOP)
handleSkippedRecursiveCall(callNode);
return;
}
"
maybe you should move the if check inside the function. You could try this way to reduce the Options::handleRecur as low as possible.
I think you could continue to narrow down the usage of OPtions::HandleREcur(). I mean maybe you could put the option check inside the function.
For example,
"// Check if this recursive call should be skipped
if (shouldSkipRecursiveCall(callNode, funObjVar))
{
// In TOP mode, set return value and stores to TOP
// In WIDEN\_ONLY/WIDEN\_NARROW, just skip (WTO handles it)
if (Options::HandleRecur() == TOP)
handleSkippedRecursiveCall(callNode);
return;
}
"
maybe you should move the if check inside the function. You could try this way to reduce the Options::handleRecur as low as possible.
I think you could continue to narrow down the usage of OPtions::HandleREcur(). I mean maybe you could put the option check inside the function.
For example,
"// Check if this recursive call should be skipped
if (shouldSkipRecursiveCall(callNode, funObjVar))
{
// In TOP mode, set return value and stores to TOP
// In WIDEN\_ONLY/WIDEN\_NARROW, just skip (WTO handles it)
if (Options::HandleRecur() == TOP)
handleSkippedRecursiveCall(callNode);
return;
}
"
maybe you should move the if check inside the function. You could try this way to reduce the Options::handleRecur as low as possible.
I think you could continue to narrow down the usage of OPtions::HandleREcur(). I mean maybe you could put the option check inside the function.
For example,
"// Check if this recursive call should be skipped
if (shouldSkipRecursiveCall(callNode, funObjVar))
{
// In TOP mode, set return value and stores to TOP
// In WIDEN\_ONLY/WIDEN\_NARROW, just skip (WTO handles it)
if (Options::HandleRecur() == TOP)
handleSkippedRecursiveCall(callNode);
return;
}
"
maybe you should move the if check inside the function. You could try this way to reduce the Options::handleRecur as low as possible.
I think you could continue to narrow down the usage of OPtions::HandleREcur(). I mean maybe you could put the option check inside the function.
For example,
"// Check if this recursive call should be skipped
if (shouldSkipRecursiveCall(callNode, funObjVar))
{
// In TOP mode, set return value and stores to TOP
// In WIDEN\_ONLY/WIDEN\_NARROW, just skip (WTO handles it)
if (Options::HandleRecur() == TOP)
handleSkippedRecursiveCall(callNode);
return;
}
"
maybe you should move the if check inside the function. You could try this way to reduce the Options::handleRecur as low as possible.
I think you could continue to narrow down the usage of OPtions::HandleREcur(). I mean maybe you could put the option check inside the function.
For example,
"// Check if this recursive call should be skipped
if (shouldSkipRecursiveCall(callNode, funObjVar))
{
// In TOP mode, set return value and stores to TOP
// In WIDEN\_ONLY/WIDEN\_NARROW, just skip (WTO handles it)
if (Options::HandleRecur() == TOP)
handleSkippedRecursiveCall(callNode);
return;
}
"
maybe you should move the if check inside the function. You could try this way to reduce the Options::handleRecur as low as possible.
I think you could continue to narrow down the usage of OPtions::HandleREcur(). I mean maybe you could put the option check inside the function.
For example,
"// Check if this recursive call should be skipped
if (shouldSkipRecursiveCall(callNode, funObjVar))
{
// In TOP mode, set return value and stores to TOP
// In WIDEN\_ONLY/WIDEN\_NARROW, just skip (WTO handles it)
if (Options::HandleRecur() == TOP)
handleSkippedRecursiveCall(callNode);
return;
}
"
maybe you should move the if check inside the function. You could try this way to reduce the Options::handleRecur as low as possible.
I think you could continue to narrow down the usage of OPtions::HandleREcur(). I mean maybe you could put the option check inside the function.
For example,
"// Check if this recursive call should be skipped
if (shouldSkipRecursiveCall(callNode, funObjVar))
{
// In TOP mode, set return value and stores to TOP
// In WIDEN\_ONLY/WIDEN\_NARROW, just skip (WTO handles it)
if (Options::HandleRecur() == TOP)
handleSkippedRecursiveCall(callNode);
return;
}
"
maybe you should move the if check inside the function. You could try this way to reduce the Options::handleRecur as low as possible.
I think you could continue to narrow down the usage of OPtions::HandleREcur(). I mean maybe you could put the option check inside the function.
For example,
"// Check if this recursive call should be skipped
if (shouldSkipRecursiveCall(callNode, funObjVar))
{
// In TOP mode, set return value and stores to TOP
// In WIDEN\_ONLY/WIDEN\_NARROW, just skip (WTO handles it)
if (Options::HandleRecur() == TOP)
handleSkippedRecursiveCall(callNode);
return;
}
"
maybe you should move the if check inside the function. You could try this way to reduce the Options::handleRecur as low as possible.
I think you could continue to narrow down the usage of OPtions::HandleREcur(). I mean maybe you could put the option check inside the function.
For example,
"// Check if this recursive call should be skipped
if (shouldSkipRecursiveCall(callNode, funObjVar))
{
// In TOP mode, set return value and stores to TOP
// In WIDEN\_ONLY/WIDEN\_NARROW, just skip (WTO handles it)
if (Options::HandleRecur() == TOP)
handleSkippedRecursiveCall(callNode);
return;
}
"
maybe you should move the if check inside the function. You could try this way to reduce the Options::handleRecur as low as possible.
I think you could continue to narrow down the usage of OPtions::HandleREcur(). I mean maybe you could put the option check inside the function.
For example,
"// Check if this recursive call should be skipped
if (shouldSkipRecursiveCall(callNode, funObjVar))
{
// In TOP mode, set return value and stores to TOP
// In WIDEN\_ONLY/WIDEN\_NARROW, just skip (WTO handles it)
if (Options::HandleRecur() == TOP)
handleSkippedRecursiveCall(callNode);
return;
}
"
maybe you should move the if check inside the function. You could try this way to reduce the Options::handleRecur as low as possible.
你方便把 setRecursiveCallStoresToTop改名setTopToObjInRecursion 然后把callFunPass 改名HandleFunCall吗? 改名就行
你方便把 setRecursiveCallStoresToTop改名setTopToObjInRecursion 然后把callFunPass 改名HandleFunCall吗? 改名就行
你方便把 setRecursiveCallStoresToTop改名setTopToObjInRecursion 然后把callFunPass 改名HandleFunCall吗? 改名就行
- Add collectEntryFunctions() to find functions without callers - Add analyseFromAllEntries() for analyzing from all entry points - Implement flow-sensitive join for same function called multiple times - Add ICFG and function coverage statistics in AEStat - Add allAnalyzedNodes set to track analyzed nodes across entry points - Fix bottom interval assertion errors in AbsExtAPI (handleMemcpy/handleMemset) When no main function exists, the analysis automatically starts from all entry points (functions with no callers). Each entry point is analyzed independently with fresh state. Coverage statistics now correctly track all analyzed nodes across multiple entry points. Co-Authored-By: Claude <[email protected]>
- Add new command-line option -ae-multientry (default: false) - When false (default): analyze from main() only, preserving original behavior for Test-Suite test cases - When true: analyze from all entry points (functions without callers), useful for library code without main function - If no main function exists and -ae-multientry is not set, automatically falls back to multi-entry analysis Co-Authored-By: Claude Opus 4.5 <[email protected]>
Revert the flow-sensitive join logic in handleICFGNode that was incorrectly breaking the original function entry state initialization. The previous change introduced unnecessary complexity that caused incorrect state propagation when functions are called. The multi-entry analysis feature still works correctly because each entry point is analyzed independently with clearAbstractTrace() called before each entry, so flow-sensitive join at function entries is not needed. This fixes 7 out of 8 failing test cases: - BASIC_ptr_call2-0.c.bc - LOOP_for_call-0.c.bc - CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_01.c.bc - CWE121_Stack_Based_Buffer_Overflow__CWE129_fgets_01.c.bc-widen-narrow - CWE126_Buffer_Overread__CWE129_fgets_01.c.bc - CWE126_Buffer_Overread__CWE129_fgets_01.c.bc-widen-narrow - demo.c.bc-widen-narrow The remaining failure (INTERVAL_test_10-0.c.bc) is a pre-existing bug unrelated to the multi-entry changes. Co-Authored-By: Claude Opus 4.5 <[email protected]>
1. Fix BufOverflowDetector assertion (AEDetector.cpp:482)
- When a variable is not an address type in multi-entry analysis,
conservatively return true (assume safe) instead of asserting
2. Fix undefined compare predicate assertion (AbstractInterpretation.cpp)
- Add support for FCMP_ORD and FCMP_UNO floating-point comparisons
- These predicates check for NaN conditions, conservatively return [0,1]
Co-Authored-By: Claude Opus 4.5 <[email protected]>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #1789 +/- ##
==========================================
+ Coverage 64.14% 64.17% +0.02%
==========================================
Files 243 243
Lines 24626 24670 +44
Branches 4658 4667 +9
==========================================
+ Hits 15797 15832 +35
- Misses 8829 8838 +9
🚀 New features to boost your workflow:
|
| void analyse(); | ||
|
|
||
| /// Analyze all entry points (functions without callers) | ||
| void analyseFromAllEntries(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
analyzeFromAllProgEntries
| void analyseFromAllEntries(); | ||
|
|
||
| /// Get all entry point functions (functions without callers) | ||
| std::vector<const FunObjVar*> collectEntryFunctions(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
collectProgEntryFuns
|
|
||
| /// Program entry | ||
| /// Collect all entry point functions (functions without callers) | ||
| std::vector<const FunObjVar*> AbstractInterpretation::collectEntryFunctions() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to use a deque if you can both push from back and push to front (for main). Then no std::find_if is needed later.
| icfg->getGlobalICFGNode())[PAG::getPAG()->getBlkPtr()] = IntervalValue::top(); | ||
|
|
||
| // If -ae-multientry is set, always use multi-entry analysis | ||
| if (Options::AEMultiEntry()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be by default.
| getAbsStateFromTrace( | ||
| icfg->getGlobalICFGNode())[PAG::getPAG()->getBlkPtr()] = IntervalValue::top(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be moved to handleGlobalNode? Please also make a note to explain why this assignment is done here.
svf/lib/AE/Svfexe/AEDetector.cpp
Outdated
| NodeID value_id = value->getId(); | ||
|
|
||
| assert(as[value_id].isAddr()); | ||
| // In multi-entry analysis, some variables may not be initialized as addresses |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add an example here?
Shall we also intitalize them?
SVF-tools#1789 Could you read comments in this PR?
SVF-tools#1789 Could you read comments in this PR?
|
|
||
| /// Program entry | ||
| /// Parse comma-separated function names from the -ae-entry-funcs option | ||
| static Set<std::string> parseEntryFuncNames() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move this to Options.cpp
SVF-tools#1789 Could you read comments in this PR?
SVF-tools#1789 Could you read comments in this PR?
| const SVFVar* arg1Val = call->getArgument(1); | ||
| IntervalValue strLen = getStrlen(as, arg1Val); | ||
| // no need to -1, since it has \0 as the last byte | ||
| // Skip if strLen is bottom or unbounded |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we share as much code as possible for string handling functions you have
| // Use worklist-based function handling instead of recursive WTO component handling | ||
| const ICFGNode* mainEntry = icfg->getFunEntryICFGNode(cgn->getFunction()); | ||
| handleFunction(mainEntry); | ||
| SVFUtil::errs() << "Warning: No entry functions found for analysis\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should always have at least one entry function (no caller function). May be an assert is better.
| } | ||
|
|
||
| // Analyze from each entry point independently (Scenario 2: different entries -> fresh start) | ||
| for (const FunObjVar* entryFun : entryFunctions) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think handle global should be done before entry function?
Also it would be good to add each entry icfgnode of entry function into the worklist for later abstract interpretation?
| // Analyze from each entry point independently (Scenario 2: different entries -> fresh start) | ||
| for (const FunObjVar* entryFun : entryFunctions) | ||
| { | ||
| // Clear abstract trace for fresh analysis from this entry |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
handle global node can be done outside this for loop?
It is unclear why we need to clear abstract trace here? The abstract states that for an ICFGNode A should be merged if A has two callers (if both callers are entry functions)?
| std::deque<const FunObjVar*> AbstractInterpretation::collectProgEntryFuns() | ||
| { | ||
| std::deque<const FunObjVar*> entryFunctions; | ||
| const CallGraph* callGraph = svfir->getCallGraph(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to use andersen's call graph if we have.
|
|
||
| // Analyze from this entry function | ||
| const ICFGNode* funEntry = icfg->getFunEntryICFGNode(entryFun); | ||
| handleFunction(funEntry); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to double-check handleCallsite whether andersen's call graph shall be used?
No caller functions as entries
AE traverses all callgraph node and pick the node that has no in edges, which means they are no caller functions. No caller functions can serve as entries.
Current Result (every functions as entry)
LIMIT: 7200 seconds or 64GB Memory
Result (No Caller function as entry)
TBA