Footprint Analysis: A Shape Analysis that Discovers Preconditions Hongseok Yang (Queen Mary, University of London) (Joint work with Cristiano Calcagno, Dino Distefano, and Peter O’Hearn)
Footprint Analysis: A Shape Analysis that Discovers
Preconditions
Hongseok Yang(Queen Mary, University of London)
(Joint work with Cristiano Calcagno, Dino Distefano, and Peter O’Hearn)
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp){ ……… PRESET_IRP ResetIrp,temp,tempnext; PDEVICE_EXTENSION de; ……… KeAcquireSpinLock(&de->ResetSpinLock, &Irql); ResetIrp = (PRESET_IRP)de->Flink2; while (ResetIrp !=NULL) { if (ResetIrp->Irp == Irp) { temp = (PRESET_IRP)de; tempnext = temp->Flink2; while (tempnext != ResetIrp) { temp = tempnext; tempnext = temp->Flink2; } temp->Flink2 = ResetIrp->Flink2; free(ResetIrp); break; } else if (ResetIrp->Flink2 == (PRESET_IRP)de) break; else ResetIrp = (PRESET_IRP)ResetIrp->Flink2; } KeReleaseSpinLock(&de->ResetSpinLock, Irql); …… IoCompleteRequest(Irp, IO_NO_INCREMENT);}
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
KeReleaseSpinLock(&de->ResetSpinLock, Irql);
KeAcquireSpinLock(&de->ResetSpinLock, &Irql);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp){ ……… PRESET_IRP ResetIrp,temp,tempnext; PDEVICE_EXTENSION de; ……… KeAcquireSpinLock(&de->ResetSpinLock, &Irql); ResetIrp = (PRESET_IRP)de->Flink2; while (ResetIrp !=NULL) { if (ResetIrp->Irp == Irp) { temp = (PRESET_IRP)de; tempnext = temp->Flink2; while (tempnext != ResetIrp) { temp = tempnext; tempnext = temp->Flink2; } temp->Flink2 = ResetIrp->Flink2; free(ResetIrp); break; } else if (ResetIrp->Flink2 == (PRESET_IRP)de) break; else ResetIrp = (PRESET_IRP)ResetIrp->Flink2; } KeReleaseSpinLock(&de->ResetSpinLock, Irql); …… IoCompleteRequest(Irp, IO_NO_INCREMENT);}
Footprint Analysis
• Discovers safe preconditions of a piece of code. • Only the memory footprint of the code.
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp){ ……… PRESET_IRP ResetIrp,temp,tempnext; PDEVICE_EXTENSION de; ……… KeAcquireSpinLock(&de->ResetSpinLock, &Irql); ResetIrp = (PRESET_IRP)de->Flink2; while (ResetIrp !=NULL) { if (ResetIrp->Irp == Irp) { temp = (PRESET_IRP)de; tempnext = temp->Flink2; while (tempnext != ResetIrp) { temp = tempnext; tempnext = temp->Flink2; } temp->Flink2 = ResetIrp->Flink2; free(ResetIrp); break; } else if (ResetIrp->Flink2 == (PRESET_IRP)de) break; else ResetIrp = (PRESET_IRP)ResetIrp->Flink2; } KeReleaseSpinLock(&de->ResetSpinLock, Irql); …… IoCompleteRequest(Irp, IO_NO_INCREMENT);}
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp){ ……… PXXX_RESET_IRP XXXResetIrp,temp,tempnext; PDEVICE_EXTENSION deviceExtension; ……… KeAcquireSpinLock(&deviceExtension->ResetSpinLock, &Irql); ResetIrp = (PRESET_IRP)de->Flink2; while (ResetIrp !=NULL) { if (ResetIrp->Irp == Irp) { temp = (PRESET_IRP)de; tempnext = temp->Flink2; while (tempnext != ResetIrp) { temp = tempnext; tempnext = temp->Flink2; } temp->Flink2 = ResetIrp->Flink2; free(ResetIrp); break; } else if (ResetIrp->Flink2 == (PRESET_IRP)de) break; else ResetIrp = (PRESET_IRP)ResetIrp->Flink2; } KeReleaseSpinLock(&deviceExtension->ResetSpinLock, Irql); …… IoCompleteRequest(Irp, IO_NO_INCREMENT);}
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de)
typedef struct { RESET_IRP* Flink2; IRP* Irp;…} RESET_IRP, *PRESET_IRP;
typedef struct { RESET_IRP* Flink2; …} DEVICE_EXTENSION;
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,x1) * (x1aR Irp:Irp)
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,0)
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de)(de aD Flink2: de)
(de aD Flink2:0)
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp){ ……… PXXX_RESET_IRP XXXResetIrp,temp,tempnext; PDEVICE_EXTENSION deviceExtension; ……… KeAcquireSpinLock(&deviceExtension->ResetSpinLock, &Irql); ResetIrp = (PRESET_IRP)de->Flink2; while (ResetIrp !=NULL) { if (ResetIrp->Irp == Irp) { temp = (PRESET_IRP)de; tempnext = temp->Flink2; while (tempnext != ResetIrp) { temp = tempnext; tempnext = temp->Flink2; } temp->Flink2 = ResetIrp->Flink2; free(ResetIrp); break; } else if (ResetIrp->Flink2 == (PRESET_IRP)de) break; else ResetIrp = (PRESET_IRP)BusResetIrp->Flink2; } KeReleaseSpinLock(&deviceExtension->ResetSpinLock, Irql); …… IoCompleteRequest(Irp, IO_NO_INCREMENT);}
typedef struct { RESET_IRP* Flink2; IRP* Irp;…} RESET_IRP, *PRESET_IRP;
typedef struct { RESET_IRP* Flink2; …} DEVICE_EXTENSION;
de aD Flink2: de
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de)
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,x1) * (x1aR Irp:Irp)
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,0)
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de)(de aD Flink2: de)
(de aD Flink2:0)
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp){ ……… PXXX_RESET_IRP XXXResetIrp,temp,tempnext; PDEVICE_EXTENSION deviceExtension; ……… KeAcquireSpinLock(&deviceExtension->ResetSpinLock, &Irql); ResetIrp = (PRESET_IRP)de->Flink2; while (ResetIrp !=NULL) { if (ResetIrp->Irp == Irp) { temp = (PRESET_IRP)de; tempnext = temp->Flink2; while (tempnext != ResetIrp) { temp = tempnext; tempnext = temp->Flink2; } temp->Flink2 = ResetIrp->Flink2; free(ResetIrp); break; } else if (ResetIrp->Flink2 == (PRESET_IRP)de) break; else ResetIrp = (PRESET_IRP)BusResetIrp->Flink2; } KeReleaseSpinLock(&deviceExtension->ResetSpinLock, Irql); …… IoCompleteRequest(Irp, IO_NO_INCREMENT);}
typedef struct { RESET_IRP* Flink2; IRP* Irp;…} RESET_IRP, *PRESET_IRP;
typedef struct { RESET_IRP* Flink2; …} DEVICE_EXTENSION;
de aD Flink2: deÆ de = ResetIrp
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de)
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,x1) * (x1aR Irp:Irp)
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,0)
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de)(de aD Flink2: de)
(de aD Flink2:0)
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp){ ……… PXXX_RESET_IRP XXXResetIrp,temp,tempnext; PDEVICE_EXTENSION deviceExtension; ……… KeAcquireSpinLock(&deviceExtension->ResetSpinLock, &Irql); ResetIrp = (PRESET_IRP)de->Flink2; while (ResetIrp !=NULL) { if (ResetIrp->Irp == Irp) { temp = (PRESET_IRP)de; tempnext = temp->Flink2; while (tempnext != ResetIrp) { temp = tempnext; tempnext = temp->Flink2; } temp->Flink2 = ResetIrp->Flink2; free(ResetIrp); break; } else if (ResetIrp->Flink2 == (PRESET_IRP)de) break; else ResetIrp = (PRESET_IRP)BusResetIrp->Flink2; } KeReleaseSpinLock(&deviceExtension->ResetSpinLock, Irql); …… IoCompleteRequest(Irp, IO_NO_INCREMENT);}
typedef struct { RESET_IRP* Flink2; IRP* Irp;…} RESET_IRP, *PRESET_IRP;
typedef struct { RESET_IRP* Flink2; …} DEVICE_EXTENSION;
de aD Flink2: deÆ de = ResetIrp
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de)
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,x1) * (x1aR Irp:Irp)
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,0)
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de)(de aD Flink2: de)
(de aD Flink2:0)
void XXX_CancelIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp){ ……… PXXX_RESET_IRP XXXResetIrp,temp,tempnext; PDEVICE_EXTENSION deviceExtension; ……… KeAcquireSpinLock(&deviceExtension->ResetSpinLock, &Irql); ResetIrp = (PRESET_IRP)de->Flink2; while (ResetIrp !=NULL) { if (ResetIrp->Irp == Irp) { temp = (PRESET_IRP)de; tempnext = temp->Flink2; while (tempnext != ResetIrp) { temp = tempnext; tempnext = temp->Flink2; } temp->Flink2 = ResetIrp->Flink2; free(ResetIrp); break; } else if (ResetIrp->Flink2 == (PRESET_IRP)de) break; else ResetIrp = (PRESET_IRP)BusResetIrp->Flink2; } KeReleaseSpinLock(&deviceExtension->ResetSpinLock, Irql); …… IoCompleteRequest(Irp, IO_NO_INCREMENT);}
typedef struct { RESET_IRP* Flink2; IRP* Irp;…} RESET_IRP, *PRESET_IRP;
typedef struct { RESET_IRP* Flink2; …} DEVICE_EXTENSION;
de aD Flink2: deÆ de = ResetIrp
ERROR: No IRP Field in DEVICE_EXTENSION
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de)
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,x1) * (x1aR Irp:Irp)
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,0)
(de aD Flink2: x0) * ls (RESET_IRP,Flink2) (x0,de)(de aD Flink2: de)
(de aD Flink2:0)
Footprint Analysis
Seeding
FootprintComputation
list t*;while (x!=0) {
t = x;
x = x->next;
free(t);
}
x=aÆemp
Footprint Analysis
Seeding
FootprintComputation
list t*;while (x!=0) {
t = x;
x = x->next;
free(t);
}
x=aÆemp
Footprint Analysis
Seeding
FootprintComputation
list t*;while (x!=0) {
t = x;
x = x->next;
free(t);
}
x=aÆemp
P2 P3P1
Footprint Analysis
Seeding
FootprintComputation
list t*;while (x!=0) {
t = x;
x = x->next;
free(t);
}
x=aÆemp
SpaceInvader
{P1}
{Q1,Q2}
{I1,I2,I3}
{P1}C{Q1ÇQ2}
P2 P3P1
Footprint Analysis
Seeding
FootprintComputation
list t*;while (x!=0) {
t = x;
x = x->next;
free(t);
}
x=aÆemp
SpaceInvader
{P2}
{Q10,Q11 ,Q12}
{I10,I11,I12}
{P1}C{Q1ÇQ2}
P2 P3P1
{P2}C{Q10ÇQ11ÇQ12}
Footprint Analysis
Seeding
FootprintComputation
list t*;while (x!=0) {
t = x;
x = x->next;
free(t);
}
x=aÆemp
SpaceInvader
{P3}
{P1}C{Q1ÇQ2}
P2 P3P1
{P2}C{Q10ÇQ11ÇQ12}
>
>
Footprint Analysis
Seeding
FootprintComputation
list t*;while (x!=0) {
t = x;
x = x->next;
free(t);
}
x=aÆemp
SpaceInvader
{P1}C{Q1ÇQ2}
P2 P3P1
{P2}C{Q10ÇQ11ÇQ12}
Footprint Analysis
Safe precondition
Footprint only
Seeding
FootprintComputation
SpaceInvader
Separation Logic
xay, ls (y,z)
xay * ls (y,z), emp
9y’. z!=0 Æ v=a Æ xay’ * ls (y’,z)
x y y z
y zx
Variable Convention
• Program variables: x,y,z,t,v,w• Ghost (or auxiliary) variables: a,b,c,d,….• Primed variables: x’,y’,z’,t’,v’,w’
9 w’,w’1.
x!=0 Æ z=a Æ w’!=w’1 Æ xaw’ * ls (w’,w’1) * yaw’1
Symbolic Heaps
Separation logic formulas of the form:
(x!=0 Æ z=a Æ w’!=w’1) Æ (xaw’ * ls (w’,w’1) * yaw’1)
SH = Set of all symbolic heapsGhoSH = Set of sym. heaps with ghost vars only
Footprint Computation
list t*;while (x!=0) {
t = x;
x = x->next;
free(t);
}
{ (x=aÆemp, x=aÆemp) }
{ (x=aÆls (a,0), x=0Æemp), (x=0Æemp, x=0Æemp), … }
Fixpoint Computation
2 Pfin(GhoSH, SH)
2 Pfin (GhoSH, SH)
Footprint Computation «x=x->next¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
rearr(x) : GhoSH x SH ! Pfin(GhoSH x SH)
exec(x=x->next) : GhoSH x SH ! GhoSH x SH abs : GhoSH x SH ! CanGhoSH x CanSH{ (x=aÆls a b, x=aÆls a b), (x=aÆls a b, x=bÆls a b) }
{ (x=aÆls a b, x=aÆaab), (x=aÆls a b, x=aÆaav’*ls v’ b), (x=aÆls a b*bac, x=bÆls a b*bac) }
rearr(x)(F,P) = { (F,P1), …, (F,Pn) } if SpInvRearr(x)(P) = {P1, …, Pn}= { (F*aab, P*aab) } else if P ` x=a= { (false,false) } otherwise
Footprint Computation «x=x->next¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
rearr(x) : GhoSH x SH ! Pfin(GhoSH x SH)
exec(x=x->next) : GhoSH x SH ! GhoSH x SH abs : GhoSH x SH ! CanGhoSH x CanSH{ (x=aÆls a b, x=aÆls a b), (x=aÆls a b, x=bÆls a b) }
{ (x=aÆls a b, x=aÆaab), (x=aÆls a b, x=aÆaav’*ls v’ b), (x=aÆls a b*bac, x=bÆls a b*bac) }
{ ………………………………., (x=aÆls a b*bac, x=cÆls a b*bac) }
Footprint Computation «x=x->next¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
rearr(x) : GhoSH x SH ! Pfin(GhoSH x SH)
exec(x=x->next) : GhoSH x SH ! GhoSH x SH abs : GhoSH x SH ! CanGhoSH x CanSH{ (x=aÆls a b, x=aÆls a b), (x=aÆls a b, x=bÆls a b) }
{ (x=aÆls a b, x=aÆaab), (x=aÆls a b, x=aÆaav’*ls v’ b), (x=aÆls a b*bac, x=bÆls a b*bac) }
{ ………………………………., (x=aÆls a b*bac, x=cÆls a b*bac) }{ ………………………………., (x=aÆls a b*bac, x=cÆls a c) }{ ………………………………., (x=aÆls a c*bac, x=cÆls a c) }
Footprint Computation «x=x->next¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
rearr(x) : GhoSH x SH ! Pfin(GhoSH x SH)
exec(x=x->next) : GhoSH x SH ! GhoSH x SH abs : GhoSH x SH ! CanGhoSH x CanSH{ (x=aÆls a b, x=aÆls a b), (x=aÆls a b, x=bÆls a b) }
{ (x=aÆls a b, x=aÆaab), (x=aÆls a b, x=aÆaav’*ls v’ b), (x=aÆls a b*bac, x=bÆls a b*bac) }
{ ………………………………., (x=aÆls a b*bac, x=cÆls a b*bac) }{ ………………………………., (x=aÆls a b*bac, x=cÆls a c) }{ ………………………………., (x=aÆls a c*bac, x=cÆls a c) }
List Disposal
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
x
0
List Disposal
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
x
0
List Disposal
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
x
0
t
List Disposal
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
x
0
t
List Disposal
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
x
0
t
Footprint Computation
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
Footprint Computation
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
Discovered Precondition: x=a Æ emp
x=a Æ emp
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp)
Footprint Computation
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
Discovered Precondition: x=a Æ a!=0 Æ emp
x=a Æ empx=a Æ a!=0 Æ emp
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp)
Footprint Computation
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
Discovered Precondition: x=a Æ a!=0 Æ emp
x=a Æ empx=a Æ a!=0 Æ emp
x=a Æ a!=0 Æ t=a Æ emp
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp)
Footprint Computation
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
Discovered Precondition: x=a Æ a!=0 Æ emp * aab
x=a Æ empx=a Æ a!=0 Æ emp
x=a Æ a!=0 Æ t=a Æ empx=b Æ a!=0 Æ t=a Æ emp * aab
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp)
Footprint Computation
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
Discovered Precondition: x=a Æ a!=0 Æ emp * aab
x=a Æ empx=a Æ a!=0 Æ emp
x=a Æ a!=0 Æ t=a Æ emp
x=b Æ a!=0 Æ t=a Æ emp
x=b Æ a!=0 Æ t=a Æ emp * aab
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp)
Footprint Computation
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
Discovered Precondition: x=a Æ a!=0 Æ emp * aab
x=a Æ empx=a Æ a!=0 Æ emp
x=a Æ a!=0 Æ t=a Æ emp
x=b Æ a!=0 Æ t=a Æ emp
x=b Æ a!=0 Æ t=a Æ emp * aab
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp)
Footprint Computation
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
Discovered Precondition: x=a Æ a!=0 Æ b!=0 Æ emp * aab
x=b Æ a!=0 Æ t=a Æ emp
x=a Æ empx=a Æ a!=0 Æ emp
x=a Æ a!=0 Æ t=a Æ empx=b Æ a!=0 Æ t=a Æ emp * aab
x=b Æ a!=0 Æ t=a Æ b!=0 Æ emp
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp)
Footprint Computation
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
Discovered Precondition: x=a Æ a!=0 Æ b!=0 Æ emp * aab
x=b Æ a!=0 Æ t=a Æ emp
x=a Æ empx=a Æ a!=0 Æ emp
x=a Æ a!=0 Æ t=a Æ empx=b Æ a!=0 Æ t=a Æ emp * aab
x=b Æ a!=0 Æ t=a Æ b!=0 Æ empx=b Æ a!=0 Æ t=b Æ b!=0 Æ emp
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp)
x=b Æ t=b Æ b!=0 Æ emp
Footprint Computation
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
Discovered Precondition: x=a Æ a!=0 Æ b!=0 Æ emp * aab * bac
x=b Æ a!=0 Æ t=a Æ emp
x=a Æ empx=a Æ a!=0 Æ emp
x=a Æ a!=0 Æ t=a Æ empx=b Æ a!=0 Æ t=a Æ emp * aab
x=b Æ a!=0 Æ t=a Æ b!=0 Æ empx=b Æ t=b Æ b!=0 Æ empx=c Æ t=b Æ b!=0 Æ emp * bac
Discovered Precondition: x=a Æ a!=0 Æ b!=0 Æ emp * ls a c a
Discovered Precondition: x=a Æ a!=0 Æ b!=0 Æ emp * ls a c a
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp)
Footprint Computation
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
Discovered Precondition: x=a Æ a!=0 Æ b!=0 Æ emp * aab * bac
x=b Æ a!=0 Æ t=a Æ emp
x=a Æ empx=a Æ a!=0 Æ emp
x=a Æ a!=0 Æ t=a Æ empx=b Æ a!=0 Æ t=a Æ emp * aab
x=b Æ a!=0 Æ t=a Æ b!=0 Æ empx=b Æ t=b Æ b!=0 Æ empx=c Æ t=b Æ b!=0 Æ emp * bac
x=c Æ t=b Æ b!=0 Æ emp
Discovered Precondition: x=a Æ a!=0 Æ b!=0 Æ emp * ls a c a
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp)
Footprint Computation
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
Discovered Precondition: x=a Æ a!=0 Æ b!=0 Æ emp * aab * bac
x=b Æ a!=0 Æ t=a Æ emp
x=a Æ empx=a Æ a!=0 Æ emp
x=a Æ a!=0 Æ t=a Æ empx=b Æ a!=0 Æ t=a Æ emp * aab
x=b Æ a!=0 Æ t=a Æ b!=0 Æ empx=b Æ t=b Æ b!=0 Æ empx=c Æ t=b Æ b!=0 Æ emp * bac
x=c Æ t=b Æ b!=0 Æ emp
Discovered Precondition: x=a Æ a!=0 Æ b!=0 Æ emp * ls a c
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp)
Footprint Computation
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
Discovered Precondition: x=a Æ a!=0 Æ b!=0 Æ emp * aab * bac
x=b Æ a!=0 Æ t=a Æ emp
x=a Æ empx=a Æ a!=0 Æ emp
x=a Æ a!=0 Æ t=a Æ empx=b Æ a!=0 Æ t=a Æ emp * aab
x=b Æ a!=0 Æ t=a Æ b!=0 Æ empx=b Æ t=b Æ b!=0 Æ empx=c Æ t=b Æ b!=0 Æ emp * bac
x=c Æ t=b Æ b!=0 Æ emp
Discovered Precondition: x=a Æ a!=0 Æ b!=0 Æ emp * ls a c a
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp)
Footprint Computation
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
Discovered Precondition: x=a Æ a!=0 Æ b!=0 Æ emp * aab * bac
x=b Æ a!=0 Æ t=a Æ emp
x=a Æ empx=a Æ a!=0 Æ emp
x=a Æ a!=0 Æ t=a Æ empx=b Æ a!=0 Æ t=a Æ emp * aab
x=b Æ a!=0 Æ t=a Æ b!=0 Æ empx=b Æ t=b Æ b!=0 Æ empx=c Æ t=b Æ b!=0 Æ emp * bac
x=c Æ t=b Æ b!=0 Æ emp
Discovered Precondition: x=a Æ a!=0 Æ b!=0 Æ emp * ls a c a
Loop: (x=aÆemp, x=aÆemp) (x=aÆa!=0Æaab, x=bÆa!=0Æt=aÆemp) (x=aÆa!=0Æls a c, x=cÆt=bÆb!=0Æemp)
Result: (x=aÆa=0Æemp, x=aÆa=0Æemp) (x=aÆa!=0Æb=0Æaab, x=bÆa!=0Æt=aÆb=0Æemp) (x=aÆa!=0Æc=0Æls a c, x=cÆt=bÆb!=0Æc=0Æemp)
Shape Analysis with SpaceInvader
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
(x=aÆa=0Æemp, x=aÆa=0Æemp)(x=aÆa!=0Æb=0Æaab, x=bÆa!=0Æt=aÆb=0Æemp)(x=aÆa!=0Æc=0Æls a c, x=cÆt=bÆb!=0Æc=0Æemp)
(x=aÆa=0Æemp, x=aÆa=0Æemp)(x=aÆa!=0Æb=0Æaab, x=bÆa!=0Æt=aÆb=0Æemp)(x=aÆa!=0Æc=0Æls a c, x=cÆt=bÆb!=0Æc=0Æemp)
{x=a’Æa’=0Æemp}
{x=a’Æa’!=0Æls a’ 0}
{x=a’Æa’!=0Æa’a0}
{ x=0 Æ emp }
{ x=0 Æ emp }
{ x=0 Æ emp }
Footprint Computation, Ideally
F
F0
D P C
«C¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }.
Goal:8D, if `SL{F}D{P}, then 9Fi. G=F*Fi and `SL{F*Fi}D;C{Qi}.
QG
Footprint Computation, Ideally
«C¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }.
Goal:8D, if `SL{F}D{P}, then 9Fi. G=F*Fi and `SL{F*Fi}D;C{Qi}.
«x=x->next¬{ (t=aÆx=bÆaab, t=bÆx=bÆemp) }=
{ (t=aÆx=bÆaab*bac, t=bÆx=cÆbac) }
«x=x->next¬{ (t=aÆx=bÆaab, t=bÆx=bÆemp) }=
{ (t=aÆx=bÆls a c , t=bÆx=cÆbac) }
{t=aÆx=bÆaab*bac} …….;x=x->next{t=bÆx=cÆbac}
{t=aÆx=bÆaab} free(t);t=x {t=bÆx=bÆemp}
{t=aÆx=bÆls a c } …….;x=x->next{t=bÆx=cÆbac}
Footprint Computation, Actually
«C¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }.
Goal:8D, if `SL{F}D{P}, then 9Fi. G=F*Fi and `SL{F*Fi}D;C{Qi}.
Actually: for all D, if `SL {F}D{P}, then 9Pi,Fi. Gi¶F*Fi, `SL{F*Fi}D;C{Pi},
PiµQi.
F
Fi
D P CPi
Gi
Qi
Abstraction abs
Rearrangement rearr(E)
Footprint Computation, Actually
«C¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }.
Goal:8D, if `SL{F}D{P}, then 9Fi. G=F*Fi and `SL{F*Fi}D;C{Qi}.
Actually: for all D, if `SL {F}D{P}, then 9Pi,Fi. Gi¶F*Fi, `SL{F*Fi}D;C{Pi},
PiµQi.
F
Fi
D P CPi
Gi
Qi
Abstraction abs
Rearrangement rearr(E)
But, only abs and rearr(E)!
Footprint Computation, Actually
«C¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }.
Goal:8D, if `SL{F}D{P}, then 9Fi. G=F*Fi and `SL{F*Fi}D;C{Qi}.
Actually: for all D, if `SL {F}D{P}, then 9Pi,Fi. Gi¶F*Fi, `SL{F*Fi}D;C{Pi},
PiµQi.
F D P free(t)
But, only abs and rearr(E)!
Fi Pi
proof rule for free(t) in sep. logic
Footprint Computation, Actually
«C¬ : Pfin(GhoSH x SH) ! Pfin(GhoSH x SH)
Supp. «C¬{ (F,P) } = { (G1,Q1), (G2,Q2) }.
Goal:8D, if `SL{F}D{P}, then 9Fi. G=F*Fi and `SL{F*Fi}D;C{Qi}.
Actually: for all D, if `SL {F}D{P}, then 9Pi,Fi. Gi¶F*Fi, `SL{F*Fi}D;C{Pi},
PiµQi.
F D P free(t)
But, only abs and rearr(E)!
Fi PiFi
Sound because of Frame Rule in sep. log.
{F}D{P}
{F*Fi}D{P*Fi} {P*Fi}free(t){Pi}
{P*Fi}D;free(t){Pi}
proof rule for free(t) in sep. logic
Backward Footprint Computation
list t*;while (x!
=0) { t = x; x = x-
>next; free(t);}
Backward:
assert(x!=0);t = x;x = x->next;free(t);assert(x=0);
Forward:
assert(x!=0);t = x;x = x->next;free(t);assert(x=0);
Experiments with List Programs
MacBook, 2GH Intel Core 2 Duo. 2GB Mem.
…x=a Æ y=b Æ ls a 0
…
append.c
merge.c…
x=a Æ y=c Æ ls a b * ls c d
…
Experiments with Firewire
MacBook, 2GH Intel Core 2 Duo. 2GB Mem.
t1394_SetAddressData
t1394Diag_CancelIrp
t1394_GetAddressData
t1394_SetAddressDataFix
t1394Diag_CancelIrpFix
t1394_GetAddressDataFix