Javascript:Hazard Builds: Difference between revisions

Jump to navigation Jump to search
(→‎Static Analysis for Rooting Hazards: stuff about heap writes)
Line 11: Line 11:
=== Diagnosing a rooting hazards failure ===
=== Diagnosing a rooting hazards failure ===


Click on the '''H''' build link, select the "Job details" pane on the bottom right, follow the "Inspect Task" link, and download the "public/build/hazards.txt.gz" file.
Click on the '''H''' build link, select the "Job details" pane on the bottom right, follow the "Inspect Task" link, and download the "<code>public/build/hazards.txt.gz</code>" file.


Example snippet:
Example snippet:
Line 40: Line 40:
</pre>
</pre>


This means that a rooting hazard was discovered at js/src/jsopcode.cpp line 1866, in the function DecompileExpressionFromStack (it is prefixed with the filename because it's a static function.) The problem is that they're an unrooted variable 'ed' that holds an ExpressionDecompiler live across a call to decompilePC. "Live" means that the variable is used after the call to decompilePC returns. decompilePC may trigger a GC according to the static call stack given starting from the line beginning with "GC Function:". The hazard itself has some barely comprehensible Assume(...) and Call(...) gibberish that describes the exact path of the variable into the function call. That stuff is rarely useful -- usually, you'll only need to look at it if it's complaining about a temporary and you want to know where the temporary came from. The type 'ExpressionDecompiler' is believed to hold pointers to GC-controlled objects of some sort. The analysis currently does not describe the exact field it is worried about.
This means that a rooting hazard was discovered at <code>js/src/jsopcode.cpp</code> line 1866, in the function <code>DecompileExpressionFromStack</code> (it is prefixed with the filename because it's a static function.) The problem is that they're an unrooted variable '<code>ed</code>' that holds an <code>ExpressionDecompiler</code> live across a call to <code>decompilePC</code>. "Live" means that the variable is used after the call to <code>decompilePC</code> returns. <code>decompilePC</code> may trigger a GC according to the static call stack given starting from the line beginning with "GC Function:". The hazard itself has some barely comprehensible Assume(...) and Call(...) gibberish that describes the exact path of the variable into the function call. That stuff is rarely useful -- usually, you'll only need to look at it if it's complaining about a temporary and you want to know where the temporary came from. The type '<code>ExpressionDecompiler</code>' is believed to hold pointers to GC-controlled objects of some sort. The analysis currently does not describe the exact field it is worried about.


To unpack this a little, the analysis is saying the following can happen:
To unpack this a little, the analysis is saying the following can happen:


* ExpressionDecompiler contains some pointer to a GC thing. For example, it might have a field 'obj' of type 'JSObject*'.
* <code>ExpressionDecompiler</code> contains some pointer to a GC thing. For example, it might have a field '<code>obj</code>' of type '<code>JSObject*</code>'.
* DecompileExpressionFromStack is called.
* <code>DecompileExpressionFromStack</code> is called.
* A pointer is stored in that field of the 'ed' variable.
* A pointer is stored in that field of the '<code>ed</code>' variable.
* decompilePC is invoked, which calls ValueToSource, which calls Invoke, which eventually calls js::MinorGC
* <code>decompilePC</code> is invoked, which calls <code>ValueToSource</code>, which calls <code>Invoke</code>, which eventually calls <code>js::MinorGC</code>
* during the resulting garbage collection, the object pointed to by ed.obj is moved to a different location. All pointers stored in the JS heap are updated automatically, as are all rooted pointers. ed.obj is not, because the GC doesn't know about it.
* during the resulting garbage collection, the object pointed to by <code>ed.obj</code> is moved to a different location. All pointers stored in the JS heap are updated automatically, as are all rooted pointers. <code>ed.obj</code> is not, because the GC doesn't know about it.
* after decompilePC returns, something accesses ed.obj. This is now a stale pointer, and may refer to just about anything -- the wrong object, an invalid object, or whatever. Badness 10000, as TeX would say.
* after <code>decompilePC</code> returns, something accesses <code>ed.obj</code>. This is now a stale pointer, and may refer to just about anything -- the wrong object, an invalid object, or whatever. Badness 10000, as TeX would say.


=== Diagnosing a heap write hazard failure ===
=== Diagnosing a heap write hazard failure ===
Confirmed users
329

edits

Navigation menu