Post on 17-Jul-2015
Inter-Prozedurale Zeigeranalyse
Skalierung durch Deklarativität➊ Nutzen, Einsatzgebiete, Beispiele➋ Intra- und kontext-sensitive interprozedurale Zeigeranalyse➌ Skalierung durch Binary Decision Diagrams (BDDs)➍ Deklarative Spezifikation mit Datalog➎ Tools: bddbddb Tim Furche (Folien basieren auf PDLI-Tutorial von J. Whaley)
!"#
!$#
!"#
!$#
!%#
&#
!'#
'#
classIntObj{publicintvalue;}
publicclassBinky(){publicstaticvoidmain(String[]args){IntObjx;//AllocatethepointersxandyIntObjy;//(butnottheIntObjpointees)x=newIntObj();//AllocateanIntObjpointee//andsetxtopointtoitx.value=42;//Dereferencextostore42initspointeey.value=13;//CRASH‐‐ydoesnothaveapointeeyety=x;//Pointerassignmentsetsytopointtox'spointeey.value=13;//Deferenceytostore13inits(shared)pointee}}
Vorlesung Compilerbau, Wintersemester 2008/09
Definition „Zeigeranalyse“
Einfach? Man schaue sich die letzte Zuweisung an …
7
➀ Zeigeranalyse: Nutzen, Einsatzgebiete, Beispiele
❛❛Worauf zeigt ein Zeiger/Objektvariable?
p=q;r=p.val;
p=q;r=p.f();
...f(){returnthis.val}
p=q;r=p.f(p);
...f(){ifp.equals(“Caesar”)returnpelsereturnthis.val}
Alias Inter-Prozedural Kontext-sensitiv
Unentscheidbar (im allgemeinen)
nicht approximierbar mit beschränktem Qualitätsverlust
lange keine skalierbaren Algorithmen für (kontext-sensitive) Zeigeranalyse
Vorlesung Compilerbau, Wintersemester 2008/09
Definition „Zeigeranalyse“
Zeigeranalyse: worauf zeigen die Zeiger eines Programs
kontext-sensitiv – berücksichtigt unterschiedliche Aufrufkontexte
Unifikations-basiert vs. Inklusions-basiert
8
➀ Zeigeranalyse: Nutzen, Einsatzgebiete, Beispiele
n=f(o);m=f(p);
...f(i){returni};
!" #"
$" %"
!" #"
$" %"
kontext-insensitiv kontext-sensitiv
n=o;m=p;m=q;n=m;
!" #"
$" %"
%"
!" #"
$" %"
%"
Unifikations-basiert Inklusions-basiert
Vorlesung Compilerbau, Wintersemester 2008/09
Einsatz: Methodenaufruf
Methodenaufruf in OO-Programmen: Java, C++ (nur virtual)
Zeigeranalyse: liefert präzisen Typ des Objekts
hier: o Typ T, sein präziser Typ ist T2
falls Typ eindeutig: unbedingter Sprung zur Methode
hier: Sprung zum Code von m in T2
Ersparnis: Analyse des Typs von o zur Laufzeit & Verwendung der Methodentabelle
wichtiger Bestandteil in Compilern für C++, Java (insbes. auch JIT)
9
➀ Zeigeranalyse: Nutzen, Einsatzgebiete, Beispiele
To=newT1();o=l.transform(o);o.m();
Tl(To){returnnewT2()}
Vorlesung Compilerbau, Wintersemester 2008/09
Einsatz: Alias-Analyse
Zeigeralias verbreitet in C, C++, Java
Zeiger verweisen auf das gleiche (Heap-) Objekt
Änderungen an dem Objekt betreffen Wert alle beteiligten Zeiger
Erkennung von Zeigeralias nötig, z.B., für
Propagation von Konstantenwerten (u.U. sogar Einsparen von Variablen) über Zeiger
statische Berechnung von Sprungadressen (bei Verwendung von Funktionszeigern)
10
➀ Zeigeranalyse: Nutzen, Einsatzgebiete, Beispiele
p.val=1;q.val=2;
x=p.val;
q=newValue();p=q;
q=newValue();p=newValue();
x=2
x=1
p Alias von q
Vorlesung Compilerbau, Wintersemester 2008/09
Einsatz: Fehlererkennung
Ziel: Auffinden von „verdächtigen“ Codefragmenten
Zugriff auf bereits freigegebenen Speicher → Aliasanalyse
„schmutzige“ Verwendung von Eingaben → z.B. SQL Injection
Pufferüberlauf beim Zugriff auf Arrays → dynamische Bereichstests
aber: verhältnismäßig teuer → statische Analyse zur Minimierung der Bereichstests
11
➀ Zeigeranalyse: Nutzen, Einsatzgebiete, Beispiele
q=newValue();p=q;
deletep;deleteq;
Vorlesung Compilerbau, Wintersemester 2008/09
Einsatz: SQL Injection
„Schmutzige“ (tainted) Verwendung von Eingaben in SQL Anfragen
Benutzereingabe (z.B. aus Webformular) wird direkt verwendet zur
Konstruktion von eingebetteten Datenbankanfragen (z.B. über JDBC)
z.B. Variablen $n und $p für Benutzername und Passwort
12
➀ Zeigeranalyse: Nutzen, Einsatzgebiete, Beispiele
SELECTbalanceFROMAccountWHEREname=‘$n’andpassword=‘$p’
SELECTbalanceFROMAccountWHEREname=‘JuliusCaesar’‐‐’andpassword=‘...’
Angreifer: als Benutzername einen Ausdruck
mit Symbolen oder Wörtern, die in SQL spezielle Bedeutung haben
z.B. Kommentarzeichen ‘‐‐’
Vorlesung Compilerbau, Wintersemester 2008/09
Einsatz: Pufferüberlauf
Problem: Eingaben (oder Ergebnisse), die Pufferplatz überschreiten
typisch: String als Zeichen-Array mit fixer Größe k, Eingabe > k
Lösung: dynamische Überprüfung der Puffer/Array Grenzen
in Java automatisch durch Compiler garantiert
Problem: naives Einfügen bei allen Arrayzugriffen sehr teuer
Lösung: Zeigeranalyse, um festzustellen, wo Überlauf möglich
z.B. bei Benutzereingaben, nicht begrenzten Schleifen, etc.
13
➀ Zeigeranalyse: Nutzen, Einsatzgebiete, Beispiele
Vorlesung Compilerbau, Wintersemester 2008/09
Intra-Prozedurale Analyse
Intra-Prozedural: innerhalb einer Prozedur
keine Aufrufe anderer Prozeduren / Methoden / etc.
Pointer- bzw. Objektvariablen zeigen auf Heap-Objekte; liegen auf Stack
Heap-Zeiger zeigen auf andere Heap-Objekte
16
o1:p=newA();o2:q=newA();
p.f=q; r=p.f; s=r;
!" #$"
%" #&"
'"
("
)"
➁ Interprozedurale, kontext-sensitive Zeigeranalyse
Heap-Objekt
Objektvariable
Vorlesung Compilerbau, Wintersemester 2008/09
Aufrufgraphen
Inter-Prozedural: auch Datenfluß zwischen mehreren Prozeduren
Technik: Aufrufgraph aufstellen
Aufrufgraph := Graph (N, E) für ein Programm P, so dass
es für jede Prozedur p in P einen Knoten np ∈ N gibt
es für jeden Aufrufpunkt c in P einen Knoten nc ∈ N gibt
falls ein Aufrufpunkt c eine Prozedur p aufrufen kann⇒ gibt es eine Kante von nc nach np
17
➁ Interprozedurale, kontext-sensitive Zeigeranalyse
Vorlesung Compilerbau, Wintersemester 2008/09
Beispiel Aufrufgraph
18
Name + Signatur classA{ Aval; intf(Aa){return1} Af(Aa){c1:returna.f(val); } staticvoidmain(){ val=newB(); val.val=this;c2:val.f(newA()); } }
classBextendsA{ Af(Aa){c3:returnval.f(a); } }
➁ Interprozedurale, kontext-sensitive Zeigeranalyse
!"#$%
!"#$
!"#$
%"#$
&'$
&($
&)$
!
*+,
+ Intra + Inter
Vorlesung Compilerbau, Wintersemester 2008/09
Kontext-Sensitive Analyse
mehrere Aufrufe der gleichen Funktion
unterschiedliche Parameter (u.a. Kontexte)
kontext-insensitive Analyse
kann Parameter nicht propagieren bei mehreren Aufrufen der gleichen Funktion
einfach & billig zu realisieren (Aufrufgraph)
kontext-sensitive Analyse
präziser, hier z.B. Eliminierung der Aufrufe durch Parameterpropag.: X[i]=16;
bis 2004: kein „präziser“, sklalierbarer Alg.
19
➁ Interprozedurale, kontext-sensitive Zeigeranalyse
for(i=0;i<1012;i++){c1:t1=g(0);c2:t2=g(4);c3:t3=g(9); X[i]=t1+t2+t3; } intg(intv){c4:returnf(v); } intf(intv){ return(v+1); }
Vorlesung Compilerbau, Wintersemester 2008/09
Kontext-Sensitive Analyse
Idee: „Klonen“
20
➁ Interprozedurale, kontext-sensitive Zeigeranalyse
for(i=0;i<1012;i++){c1:t1=g(0);c2:t2=g(4);c3:t3=g(9); X[i]=t1+t2+t3; } intg(intv){c4:returnf(v); } intf(intv){ return(v+1); }
for(i=0;i<1012;i++){c1: t1=g1(0);c2: t2=g2(4);c3: t3=g3(9); X[i]=t1+t2+t3; } intg1(intv){c4.1:returnf1(v);} intg2(intv){c4.2:returnf2(v);} intg3(intv){c4.3:returnf3(v);} intf1(intv){ return(v+1);} intf2(intv){ return(v+1);} intf3(intv){ return(v+1);}
Vorlesung Compilerbau, Wintersemester 2008/09
Kontext-Sensitive Analyse
Problem 1: Rekursive Prozeduren / Funktionen
Lösung: stark-verbundenen Zusammenhangskomponenten kollabieren
21
A!
G!
B! C! D!
E! F!
A!
G!
B! C! D!
E! F! E! F! E! F!
G! G!
➁ Interprozedurale, kontext-sensitive Zeigeranalyse
Vorlesung Compilerbau, Wintersemester 2008/09
Kontext-Sensitive Analyse durch Klonen
Problem 2: Exponentielle Explosion des Aufrufgraphen
22
➁ Interprozedurale, kontext-sensitive Zeigeranalyse
Vorlesung Compilerbau, Wintersemester 2008/09
Kontext-Sensitive Analyse durch Klonen
Anzahl der Klone in Top 20 Java Programmen auf Sourceforge:
23
➁ Interprozedurale, kontext-sensitive Zeigeranalyse
Vorlesung Compilerbau, Wintersemester 2008/09
Kontext-Sensitive Analyse durch Klonen
Hoffnungslos? – typisches Program ~1014 Pfade, nur 1 Byte pro Klon
256 TBi Speicher > 12fache der Größe der “Library of Congress”
so viel Speicher verbraucht so viel Energie wie ~120 Haushalte
Sequentielles Lesen von Festplatte: ~70 Tage
Trotzdem: Es geht mit folgender Beobachtung:
Viele der Pfade sind weitgehend identisch, Kontexte sehr ähnlich
Datenstruktur, die die hoch-redundante Aufrufgraph Relation kompakt kompakt (“exponentially more succinct”) darstellen kann
Lösung: Binary Decision Diagram (Binäre Entscheidungsdiagramm)
24
➁ Interprozedurale, kontext-sensitive Zeigeranalyse
Vorlesung Compilerbau, Wintersemester 2008/09
Aufrufgraph als boolesche Funktion
Aufrufgraph repräsentiert als Relation:
calls(A,B), calls(A,C), calls(A,D), calls(B,D), calls(C,D)
Relation repräsentiert als boolesche Funktion
A = 00, B = 01, C = 10, D = 11 (Aufzählung der Domain)
27
➂ Skalierung durch Binary Decision Diagrams (BDDs)
B
D
C
A
!"#$% &#%
!"# !$# !%# !&# '#
(# (# (# (# (#
(# (# (# "# "#
(# (# "# (# "#
(# (# "# "# "#
(# "# (# (# (#
(# "# (# "# (#
(# "# "# (# (#
(# "# "# "# "#
"# (# (# (# (#
"# (# (# "# (#
"# (# "# (# (#
"# (# "# "# "#
"# "# (# (# (#
"# "# (# "# (#
"# "# "# (# (#
"# "# "# "# (#
B
D
C
A 00
10 01
11
Vorlesung Compilerbau, Wintersemester 2008/09
Binary Decision Diagrams (Beispiel)
28
➂ Skalierung durch Binary Decision Diagrams (BDDs)
!"#$% &#%
!"# !$# !%# !&# '#
(# (# (# (# (#
(# (# (# "# "#
(# (# "# (# "#
(# (# "# "# "#
(# "# (# (# (#
(# "# (# "# (#
(# "# "# (# (#
(# "# "# "# "#
"# (# (# (# (#
"# (# (# "# (#
"# (# "# (# (#
"# (# "# "# "#
"# "# (# (# (#
"# "# (# "# (#
"# "# "# (# (#
"# "# "# "# (#
!"#
!$#
!%# !%#
!$# !$# !$#
&# &# &# '# &# &# &# &#
!"#
!$#
!%# !%#
!$# !$# !$#
&# '# '# '# &# &# &# '#
!'#
!"#$%&'"
("#$%&'"
Vorlesung Compilerbau, Wintersemester 2008/09
!"#
!$#
!%# !%#
!$# !$# !$#
&# &# &# &# &# &# &#
!"#
!$#
!%# !%#
!$# !$# !$#
&# &# &# &#
!'#
'#'# '# '# '#
&#()*+,#
'#()*+,#
Reduziertes BDD (Beispiel)
Eliminierung von nicht-eindeutigen Knoten
gleiche Variable & gleiche 1- und 0-Nachfolger
29
➂ Skalierung durch Binary Decision Diagrams (BDDs)
Vorlesung Compilerbau, Wintersemester 2008/09
Reduziertes BDD II (Beispiel)
30
➂ Skalierung durch Binary Decision Diagrams (BDDs)
!"#
!$#
!%# !%#
!$# !$# !$#
!"#
!$#
!%# !%#
!$# !$# !$#
&#
!'#
'#
&#()*(#
'#()*(#
Vorlesung Compilerbau, Wintersemester 2008/09
Reduziertes BDD III (Beispiel)
31
➂ Skalierung durch Binary Decision Diagrams (BDDs)
!"#
!$#
!%# !%#
!"#
!%# !%#
!$# !$#
&#
!'#
'#
&#()*(#
'#()*(#
Vorlesung Compilerbau, Wintersemester 2008/09
Reduziertes BDD IV (Beispiel)
Eliminierung von redundanten Knoten
1- und 0-Nachfolger selber Knoten
32
!"#
!$#
!%# !%#
!"#
!%#
!$# !$#
&#
!'#
'#
&#()*(#
'#()*(#
➂ Skalierung durch Binary Decision Diagrams (BDDs)
Vorlesung Compilerbau, Wintersemester 2008/09
Reduziertes BDD V (Beispiel)
33
!"#
!$#
!"#
!$#
!%#
&#
!'#
'#
&#()*(#
'#()*(#
➂ Skalierung durch Binary Decision Diagrams (BDDs)
Vorlesung Compilerbau, Wintersemester 2008/09
Geordnete, reduzierte BDDs (ROBDDs)
Binary Decision Diagram (BDD) :=
gerichteter, azyklischer Graph mit Wurzel bestehend aus
einer oder zwei Blättern (keine ausgehenden Kanten), die mit 0 bzw. 1 gelabelt sind;
jeder andere Knoten ist ein Variablenknoten u mit genau 2 ausgehenden Kanten low(u) und high(u) und einer Variablen var(u) als Label
Geordnetes BDD :=
auf allen Pfaden von der Wurzel kommen Variablen in gleicher Ordnung vor
Reduziertes BDD :=
unique – var(u) = var(v) ∧ low(u) = low(v) ∧ high(u) = high(v) ⇒ u = v
non-redundant – ∀ u: low(u) ≠ high(u)
34
➂ Skalierung durch Binary Decision Diagrams (BDDs)
Vorlesung Compilerbau, Wintersemester 2008/09
Variablenordnung in BDDs
Problem: Größe & Form hängt von Reihenfolge der Variablen ab
35
➂ Skalierung durch Binary Decision Diagrams (BDDs)
!"#
!$#
!%#
&# "#
!'#
!"#
!$#
!%#
&# "#
!'#
!$#
!'#
x1 ∧ x2 ∨ x3 ∧ x4
x1 < x2 < x3 < x4 x1 < x3 < x2 < x4
Vorlesung Compilerbau, Wintersemester 2008/09
Variablenordnung in BDDs
36
➂ Skalierung durch Binary Decision Diagrams (BDDs)
x1
x3
0
x3
1
x5
0
x5
1
x5
0
x5
1
x7
0
x7
1
x7
0
x7
1
x7
0
x7
1
x7
0
x7
1
x8
1
0
0
x6
0
x6
1
x4
0
x4
1
x4
0
x4
1x2
0
x2
1
x2
0
x2
1
x2
0
x2
1
x2
0
x2
1
1
10
0
1
0
1
0
1
0
1
0
1
0
1
0
1
10
0
1
0
1
0
1
10
0
1
10
x1
x2
1
x3
0
0
1
1
x4
1
x5
0
0
1
x6
1
x7
0
0
1
x8
1
0
0
1 0
Gleiche Funktion:
Vorlesung Compilerbau, Wintersemester 2008/09
Variablenordnung in BDDs
Schlimmer:
Bestimmen der optimalen Variablenordnung für eine gegebene boolesche Funktion ist NP-vollständig
Bestimmen selbst einer um einen konstanten Faktor c > 1 schlechteren Ordnung ist noch NP-vollständig (also APX-hart)
In der Praxis: Zahlreiche, effiziente Heuristiken
große Zahl von BDD-Libraries → http://en.wikipedia.org/wiki/Binary_decision_diagram
Kanonisches ROBDD zu jeder booleschen Funktion f(x1, …, xn)
gibt es genau ein ROBDD mit Variablenordnung x1 < … < xn
daher: effizienter Equivalenztest
37
➂ Skalierung durch Binary Decision Diagrams (BDDs)
Vorlesung Compilerbau, Wintersemester 2008/09
Manuelle Zeigeranalyse mit BDDs
Implementierung komplex, fehleranfällig, schwer zu optimieren
daher: deklarative Spezifikation, automatische Transformation in BDDs
40
➃ Deklarative Spezifikation mit Datalog
>50 Seiten, SAS 2002 ~ 15 Zeilen, PLDI 2004
Vorlesung Compilerbau, Wintersemester 2008/09
Spezifikationssprache: Datalog
Datalog: (rekursive) Logik über Relationen mit endlicher Domain
siehe zweiter Teil der Vorlesung, hier nur intuitive Behandlung
Semantik: wenn Konjunktion der Atome im Rumpf war ist, dann auch Kopf
Variablen entsprechend instantiiert, jede Var. im Kopf auch im Rumpf
41
➃ Deklarative Spezifikation mit Datalog
vPointsTo(q,o).
Assignment(p,q).
vPointsTo(V1,O):‐Assignment(V1,V2), vPointsTo(V2,O).
Prädikat- (Relations-) Symbol
Fact
Regel (Kopf :- Rumpf)
keine Funktionssymbole; nur stratifizierte Negation
Vorlesung Compilerbau, Wintersemester 2008/09
Extraktion von Fakten
Zurück zum Beispielprogram (intra-prozedural):
42
o1:p=newA();o2:q=newA();
p.f=q; r=p.f; s=r;
!" #$"
%" #&"
'"
("
)"
vPointsTo(p,o1).vPointsTo(q,o2).Store(p,f,q).Load(p,f,r).Assign(s,r).
➃ Deklarative Spezifikation mit Datalog
Ziel:
Vorlesung Compilerbau, Wintersemester 2008/09
Zeiger zwischen Heapobjekten
Ableitbar aus Belegung von Objektvariablen (vPointsTo) & Heapzuweisungen (Store)
43
➃ Deklarative Spezifikation mit Datalog
hPointsTo(Obj1,Att,Obj2):‐Store(Var1,Att,Var2), vPointsTo(Var1,Obj1), vPointsTo(Var2,Obj2).
Store(p,f,q).vPointsTo(p,o1).vPointsTo(q,o2).
!" #$"
%" #&"
!"
∧ →
hPointsTo(o1,f,o2).
wegenp.f=q;
Vorlesung Compilerbau, Wintersemester 2008/09
Zugriff auf Heapzeiger
Ableitbar aus Belegung von Objektvariablen (vPointsTo) & Heapzeigern (hPointsTo) sowie Heapzugriffen (Load)
44
➃ Deklarative Spezifikation mit Datalog
vPointsTo(Var2,Obj2):‐Load(Var1,Att,Var2), vPointsTo(Var1,Obj1), hPointsTo(Obj1,Att,Obj2).
Load(p,f,r).vPointsTo(p,o1).hPointsTo(o1,f,o2). ∧ →
vPointsTo(r,o2).!" #$"
#%"
&"
!"
wegenr=p.f;
Vorlesung Compilerbau, Wintersemester 2008/09
Alias-Auflösung
Ableitbar aus Belegung von Objektvariablen (vPointsTo) & Heapzuweisungen (Store)
45
➃ Deklarative Spezifikation mit Datalog
vPointsTo(Var1,Obj) :‐Assign(Var1,Var2), vPointsTo(Var2,Obj).
Assign(s,r).vPointsTo(r,o2). ∧ →
vPointsTo(s,o2).
wegens=r;
!" #$"
%" #&"
'"
("
!"
Vorlesung Compilerbau, Wintersemester 2008/09
Vollständiger Analysalgorithmus
Das wars … damit haben wir einen Zeigeranalysalgorithmus
der schneller oder gleich-schnell wie manuelle Ansätze ist
46
➃ Deklarative Spezifikation mit Datalog
hPointsTo(Obj1,Att,Obj2) :‐Store(Var1,Att,Var2),
vPointsTo(Var1,Obj1),
vPointsTo(Var2,Obj2).
vPointsTo(Var2,Obj2):‐ Load(Var1,Att,Var2),
vPointsTo(Var1,Obj1),
hPointsTo(Obj1,Att,Obj2).
vPointsTo(Var1,Obj):‐ Assign(Var1,Var2),
vPointsTo(Var2,Obj).
Vorlesung Compilerbau, Wintersemester 2008/09
Gleich schnell?
Übersetzung der Datalog Spezifikation in BDDs
Datalog → relationale Algebra → BDDs → Domain-optimierte BDDs
Details siehe:
J. Whaley and M. S. Lam. Cloning-based context-sensitive pointer alias analysis using binary decision diagrams. In Proc. ACM Conf. on Programming Language Design and Implementation (PLDI), 2004. ACM.
Implementiert in bddbddb
Datalog Engine basierend auf BDDs
http://bddbddb.sourceforge.net/
47
➃ Deklarative Spezifikation mit Datalog
Vorlesung Compilerbau, Wintersemester 2008/09
Gleich schnell?
48
➃ Deklarative Spezifikation mit Datalog
Optimierungsstufen
Vorlesung Compilerbau, Wintersemester 2008/09
Gleich schnell?
49
➃ Deklarative Spezifikation mit Datalog
Vorlesung Compilerbau, Wintersemester 2008/09
Gleich schnell?
50
➃ Deklarative Spezifikation mit Datalog
Vorlesung Compilerbau, Wintersemester 2008/09
Literatur zur Interprozeduralen Zeigeranalyse
Basiswissen:
Aho, Lam, Sethi, Ullman: “Compilers”, 2nd Edition, Kapitel 12
M. S. Lam, J. Whaley, V. B. Livshits, M. C. Martin, D. Avots, M. Carbin, and C. Unkel. Context-sensitive program analysis as database queries. In Proc. ACM Symp. on Principles of Database Systems (PODS), 2005. ACM.
Weiterführende Literatur:
V. T. Chakaravarthy and S. Horwitz. On the non-approximability of points-to analysis. Acta Inf., 38(8):587–598, 2002.
J. Whaley and M. S. Lam. Cloning-based context-sensitive pointer alias analysis using binary decision diagrams. In Proc. ACM Conf. on Programming Language Design and Implementation (PLDI), 2004. ACM.
53
Fragen