Skip to content

Instantly share code, notes, and snippets.

@eevee
Created March 15, 2012 22:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eevee/2047470 to your computer and use it in GitHub Desktop.
Save eevee/2047470 to your computer and use it in GitHub Desktop.
gcc-python-plugin
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="http://stuff.veekun.com/reset.css"/>
<style type="text/css">
html {
height: 100%;
}
body {
display: box;
box-orient: vertical;
min-height: 100%;
min-width: 100%;
font-family: sans-serif;
}
#header {
background: hsl(210, 100%, 50%);
}
#header-top {
padding: 1em;
color: white;
}
#nav {
padding: 1em;
background: hsl(0, 0%, 83%);
color: black;
}
#footer {
box-flex: 1;
background: hsl(0, 0%, 30%);
box-shadow: inset 0 3px 3px -3px black;
}
#reports > li {
display: box;
box-orient: horizontal;
width: 100%;
border-top: 1px solid black;
}
.source {
font-family: monospace;
font-size: 12px;
padding: 1em;
background: white;
box-flex: 1;
height: 100%;
line-height: 1.33;
}
.source table {
width: 100%;
}
.source tr:nth-child(2n) {
background: hsl(0, 0%, 93%);
}
.source tr:hover {
background: hsl(210, 30%, 87%);
}
.states {
font-size: 12px;
background: hsl(15, 3%, 83%);
top: 0.5em;
height: 100%;
border-left: 1px solid hsl(0, 0%, 70%);
}
.states li {
padding: 0.5em;
margin: 1em;
background: white;
border: 1px solid hsl(0, 0%, 70%);
}
var {
color: navy;
}
var.leak {
color: darkred;
font-weight: bold;
background: hsl(0, 100%, 90%);
}
.flow-line {
background: hsl(210, 80%, 60%);
background-clip: content-box;
}
.flow-empty, .flow-line {
width: 2px;
padding: 0 5px;
}
.flow-dot {
display: block;
background: hsl(210, 80%, 60%);
outline: 1px solid rgba(100%, 100%, 100%, 0.5);
height: 6px;
width: 6px;
margin: 0 -2px;
border-radius: 100px;
outline-radius: 100px;
}
</style>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="gcc-python-plugin/libcpychecker/html/extlib/prefixfree-1.0.4.min.js"></script>
<script type="text/javascript">
$(function() {
"use strict";
var $reports = $('#reports > li');
$reports.each(function() {
var $report = $(this);
var $source = $report.find('.source table');
var first_line = parseInt($source.data('first-line'), 10);
var $lines = $source.find('tr');
var $line_index = {};
$lines.each(function(idx) {
var $line = $(this);
var lineno = first_line + idx;
$line.prepend($('<td>').append(lineno));
$line_index[lineno] = $line;
});
var $states = $report.find('.states li');
var source_flow = [];
var last_line = null;
$states.each(function() {
var $state = $(this);
var lineno = parseInt($state.data('line'), 10);
var $assoc_line = $line_index[lineno];
$state.data('line-element', $assoc_line);
$state.hover(
function() { $assoc_line.css('background', 'red'); },
function() { $assoc_line.css('background', ''); }
);
var flow;
console.log(last_line, lineno, source_flow);
if (! last_line || last_line > lineno) {
flow = [];
source_flow.push(flow);
}
else {
flow = source_flow[source_flow.length - 1];
}
flow.push(lineno);
last_line = lineno;
});
$.each($line_index, function(lineno, $row) {
var $paths = $();
$.each(source_flow, function(idx, flow) {
if (! flow.length) {
return;
}
else if (flow[0] >= lineno) {
$paths = $paths.add($('<td>', { "className": "flow-line" }));
console.log($paths);
if (flow[0] == lineno) {
flow.shift();
$paths.last().append($('<span>', { "class": "flow-dot" }));
}
}
});
//$row.prepend($paths);
});
});
});
</script>
</head>
<body>
<header id="header">
<div id="header-top">
<div id="title">GCC Python Plugin</div>
<div id="filename">/home/david/coding/pycon-2012/bug.c</div>
</div>
<nav id="nav">
Function: make_a_list_of_random_ints_badly
Report: 1 2 3 4
Bug 3 « »
</nav>
</header>
<ol id="reports">
<li>
<div class="source">
<table data-first-line="3">
<tr><td class="flow-line"></td><td class="flow-empty"></td><td><pre>#include &lt;Python.h&gt;</pre></td></tr>
<tr><td class="flow-line"></td><td class="flow-empty"></td><td><pre></pre></td></tr>
<tr><td class="flow-line"></td><td class="flow-empty"></td><td><pre>PyObject *</pre></td></tr>
<tr><td class="flow-line"></td><td class="flow-empty"></td><td><pre>make_a_list_of_random_ints_badly(PyObject *self,</pre></td></tr>
<tr><td class="flow-line"></td><td class="flow-empty"></td><td><pre> PyObject *args)</pre></td></tr>
<tr><td class="flow-line"></td><td class="flow-empty"></td><td><pre>{</pre></td></tr>
<tr><td class="flow-line"></td><td class="flow-empty"></td><td><pre> PyObject *<var>list</var>, *<var>item</var>;</pre></td></tr>
<tr><td class="flow-line"></td><td class="flow-empty"></td><td><pre> long <var>count</var>, <var>i</var>;</pre></td></tr>
<tr><td class="flow-line"></td><td class="flow-empty"></td><td><pre></pre></td></tr>
<tr><td class="flow-line"></td><td class="flow-empty"></td><td><pre> if (!PyArg_ParseTuple(args, "i", &amp;<var>count</var>)) {</pre></td></tr>
<tr><td class="flow-line"></td><td class="flow-empty"></td><td><pre> return NULL;</pre></td></tr>
<tr><td class="flow-line"></td><td class="flow-empty"></td><td><pre> }</pre></td></tr>
<tr><td class="flow-line"></td><td class="flow-empty"></td><td><pre></pre></td></tr>
<tr><td class="flow-line"></td><td class="flow-empty"></td><td><pre> <var>list</var> = PyList_New(0);</pre></td></tr>
<tr><td class="flow-line"></td><td class="flow-empty"></td><td><pre></pre></td></tr>
<tr><td class="flow-line"><span class="flow-dot"></span></td><td class="flow-line"><span class="flow-dot"></span></td><td><pre> for (i = 0; <var>i</var> &lt; <var>count</var>; i++) {</pre></td></tr>
<tr><td class="flow-line"><span class="flow-dot"></span></td><td class="flow-line"></td><td><pre> <var title="item: PyLongObject&#x0a;&#x0d; &nbsp; &nbsp; allocated by PyLong_FromLong()" class="leak">item</var> = PyLong_FromLong(random());</pre></td></tr>
<tr><td class="flow-line"><span class="flow-dot"></span></td><td class="flow-line"></td><td><pre> <a href="http://docs.python.org/c-api/list.html#PyList_Append" title="PyList_Append(PyObject* list, PyObject* item)">PyList_Append</a>(<var>list</var>, <var class="leak">item</var>);</pre></td></tr>
<tr><td class="flow-line"></td><td class="flow-line"></td><td><pre> }</pre></td></tr>
<tr><td class="flow-empty"></td><td class="flow-line"></td><td><pre></pre></td></tr>
<tr><td class="flow-empty"></td><td class="flow-line"><span class="flow-dot"></span></td><td><pre> return <var>list</var>;</pre></td></tr>
<tr><td class="flow-empty"></td><td class="flow-line"></td><td><pre>}</pre></td></tr>
</table>
</div>
<ol class="states">
<li data-line="10">
when PyArg_ParseTuple() succeeds <br>
taking False path
</li>
<li data-line="14">
when PyList_New() succeeds
</li>
<li data-line="16">
when considering range: 1 &lt;= count.0 &lt;= 0x7fffffff <br>
taking True path
</li>
<li data-line="17">
when PyLong_FromLong() succeeds <br>
PyLongObject allocated at: item = PyLong_FromLong(random()); <br>
ob_refcnt is now refs: 1 + N where N &gt;= 0
</li>
<li data-line="18">
when PyList_Append() succeeds<br>ob_refcnt is now refs: 2 + N where N &gt;= 0<br>'*item' is now referenced by 1 non-stack value(s): PyListObject.ob_item[0]
</li>
<li data-line="16">
when considering count.0 == (int)1 from /home/david/coding/pycon-2012/bug.c:10 <br>
taking False path
</li>
<li data-line="end">
ob_refcnt of '*item' is 1 too high <br>
was expecting final ob_refcnt to be N + 1 (for some unknown N) <br>
due to object being referenced by: PyListObject.ob_item[0] <br>
but final ob_refcnt is N + 2 <br>
found 1 similar trace(s) to this
</li>
</ol>
</li>
</ol>
<footer id="footer">
</footer>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment