these cases concolic evaluation might have an advan-
tage as it covers the activities per unit time faster, cf.
(Paduraru et al., 2023).
Listing 1 shows the main loop of the implementa-
tion pseudocode in our framework. The process starts
with the initial activity node in the graph G ( Line 2),
inserts this initial path with a single node into a work-
list W , then extracts a promising path at each step of
the loop (with several possible customizable strate-
gies for evaluating path priorities), and continues its
forward execution, Line 7. The worklist W is a pri-
ority queue sorted by a priority of elements (paths).
By default, this priority is calculated based on how
deep in the G exploration tree the path is now. By de-
fault, paths that are at the top of the exploration tree
are promoted so that the algorithm is able to traverse a
variety of paths and activities in less time, rather than
focusing on single long paths with common activity
nodes. However, depending on the test goal, the user
is free to override this default behavior by using func-
tion hooks in our framework.
When generating new inputs to the work queue
W , the default calculation method for setting their
priority is based on the location (depth index) in the
tree where the branching constraint is reversed. Thus,
when sorting the priority queue W by priority, the de-
fault behavior is to promote changes to paths at the be-
ginning of previous paths. This is also used in (Gode-
froid et al., 2012b), but the user is free to override this
functionality with a hook function as needed.
1 // In i t the st a rt e x pl ora ti o n pat h with the e ntry n ode of
the w o rk f lo w grap h
2 star t_p at h = SM T Pa t h ([ G. e nt r y_ n od e ], p r io r ity =
MA X_P RI O RI T Y )
3 // Add t h is to t h e cur ren t Wo r kli st
4 W . a d d ( s ta rt_ pat h )
5 w hil e W . not Emp ty () :
6 c urr Pat h = W . e x tra c t ()
7 E xe c ut ePa th ( cu r rPat h , W )
Listing 1: The main loop of Symbolic execution using DFS
strategy
The code for continuing the execution of a given
path is shown in Listing 2. An execution path in this
purely symbolic model is abstracted by the code of
class SMT Path. Given knowledge of an initial set
of constraints on the variables in the DataStore (e.g.,
those propagated from annotations), Line 6 adds them
to the state of the SMT solver. Next, the implementa-
tion parses the current node to make the continuation
decision, Line 9.
When a branch node occurs, Lines 15-41, the cur-
rent path is cloned and split in two: one takes the
True branch and the other takes the False branch.
We add only the feasible paths to the future work-
list after calculating their priority and setting up the
next node for execution according to the considered
branch. It is important to note that for one of the
paths, the DataStore instance is also duplicated, Line
38. This ensures that both operate on different data
context values. This is also beneficial for paralleliza-
tion, as branches from the worklist can then be exe-
cuted in parallel. Note that the implementation pre-
sented is depth-first search (DFS) style, as the next
highest priority path continuation is the currently ac-
tively executing path, while the other is added to the
worklist and possibly executed later in the process,
Line 40.
1 Exec ut e Pa t h ( pat h : SMTPa t h , W : Wo rkl ist )
2 // Eac h p ath s t ore s the nex t n ode to ex e cut e ( i nit ial
is the ent ry nod e of the p a th )
3 c urr Nod e = pat h . ne xt N od eT o Ex ec u t e
4
5 // First , add all the c on s tr a in ts g i ven by the
Da t aS t or e ob j ect s re st r ic t io ns g iven by a nno ta t io n s
6 p a th . co nd i ti on s _s m t = D a t aS to r eT em p la te .
ge tV a r i ab le s As se rt i on s ()
7
8 // The no d e will a dva nce to the end of the W o rk f lo w
gra p h G at each i te r at i on of the pa t h
9 w h ile c ur r No d e != None :
10 // i f c urr ent n ode is not a br anc h type , jus t exe c ut e
it and ad v an c e to t he next n o de in t h e wo r kf l ow
11 if cu r rN o de . ty p e ! = B RAN C H :
12 Wo rk f lo wE x ec ut o r . Ex ecu t e ( cu rrN o de )
13 cu r rN o de = c ur r No d e . next ( )
14 // I f t h e cur r ent n ode is a branch ,
15 el s e :
16 // If br anc h n ode but t here is no sy m bo l ic v ar i abl e
use d in its c on d it i on e xp r es s io n the n j ust a d va n ce
17 if no t Ha s Sy mb o l i cV ar i ab le s ( c u rrN ode . c on d it i on )
18 // Get the re sul t of the e va l ua tio n and a d van ce
19 R e sul t = W o rk fl o wE xe c ut or . E x ec u te ( c u rr N od e )
20 c u rr N od e . ad v anc e ( Res u lt )
21 c o nt i nu e
22
23 // N o de has s y mb o li c vari a bles , b uild t h e
co nti nu a ti o n of the c u rre n t pa t h o n b o th
24 // T r ue and F a lse b ran che s with th e n ext no des and
SMT a sse rti on s nee d ed
25 ne wP a th _ on Tr u e = S MTP ath ( n o des = c u rr P at h . n ode s +
cu r rN o de . n e xt N od e ( T rue ) ,
26 co nd i ti o ns _s m t = cu r rP a th .
co nd i ti o ns _s m t + c ur r Nod e . co n di t io n )
27 ne wP a th _o n Fa l se = SM T Pa t h ( nod e s = cu r rPa th . no d es +
cu r rN o de . n e xt N od e ( F als e ) ,
28 co nd i ti o ns _s m t = cu r rP a th .
co nd i ti o ns _s m t + No t ( c urr Nod e . co n di t io n ) )
29 // T h en ch e ck wh i ch of them a r e f easi b le ,
pri o rit i ze , set th e n e xt s t ar t ing n o d es , c l one th e
30 // d a ta st o re i n st a nc e s su c h that t h ey co u ld wo r k
in para l lel , and add t h em to t he wo r kl i st
31 so lv a bl eN e wP at h s = []
32 if S MT S ol v er ( n ew Pat h_ o nT ru e ) h a s so l uti on :
33 s ol v ab le N ew Pa t hs . a d d ( n ew Pa t h_ on T ru e )
34 if S MT S ol v er ( n ew Pa t h_ o nF al s e ) has so lut i on :
35 s ol v ab le N ew Pa t hs . a d d ( n ew Pa t h_ on F al se )
36 for ne w Pa t h in so l va bl e Ne wP a th s :
37 n e wP a th . s c or e Pa t h ()
38 n e wP a th . d a ta _ st ore = cu r rP a th . d ata _st or e . c lon e ()
39 n e wP a th . n ex t No de T oE xe c ut e = c u rr N od e . ne x tN o de (
Tru e if n e wP a th == n e wP at h _o n Tr ue e l se Fa l se )
40 W. add ( n ew P at h _o nF a ls e )
41 bre a k
42 // I f at the end of the path , th e n st r eam ou t t h e
mod e l v a ri a bl e s
43 S t re a mO u t ( c u rrP ath )
Listing 2: The main loop of symbolic execution using DFS
strategy
Other implementations might also consider
breadth-first-search (BFS) style, i.e., after a branch,
both branches are added to the worklist according
to priority, and a new path must be considered at
ICSOFT 2023 - 18th International Conference on Software Technologies
272