summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorM Joonas Pihlaja <jpihlaja@cc.helsinki.fi>2009-07-24 07:42:57 +0300
committerM Joonas Pihlaja <jpihlaja@cc.helsinki.fi>2009-09-02 04:50:20 +0100
commit174c2620c82a47d067ec7b5062a4f513155a0b1f (patch)
tree461ec12fa1f16094bca6ad956ac29b44c95f763e /util
parentbb480d235882d8e7d5748a3837f9b274a8b8ac86 (diff)
[trace] Check for object stack underflow.
If the tracer's object stack underflows we want to know about is as soon as possible. This patch adds checks against the stack overflowing and aborts the program with an object stack dump if it does.
Diffstat (limited to 'util')
-rw-r--r--util/cairo-trace/trace.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c
index 3c47aafc..beeec204 100644
--- a/util/cairo-trace/trace.c
+++ b/util/cairo-trace/trace.c
@@ -829,10 +829,30 @@ static Object *current_object[2048]; /* XXX limit operand stack */
static int current_stack_depth;
static void
+ensure_operands (int num_operands)
+{
+ if (current_stack_depth < num_operands)
+ {
+ int n;
+
+ fprintf (stderr, "Operand stack underflow!\n");
+ for (n = 0; n < current_stack_depth; n++) {
+ Object *obj = current_object[n];
+
+ fprintf (stderr, " [%3d] = %s%ld\n",
+ n, obj->type->op_code, obj->token);
+ }
+
+ abort ();
+ }
+}
+
+static void
_consume_operand (void)
{
Object *obj;
+ ensure_operands (1);
obj = current_object[--current_stack_depth];
if (! obj->defined) {
_trace_printf ("dup /%s%ld exch def\n",
@@ -848,6 +868,7 @@ _exch_operands (void)
{
Object *tmp;
+ ensure_operands (2);
tmp = current_object[current_stack_depth-1];
tmp->operand--;
current_object[current_stack_depth-1] = current_object[current_stack_depth-2];
@@ -871,6 +892,7 @@ _pop_operands_to_object (Object *obj)
while (current_stack_depth > obj->operand + 1) {
Object *c_obj;
+ ensure_operands (1);
c_obj = current_object[--current_stack_depth];
c_obj->operand = -1;
if (! c_obj->defined) {
@@ -912,8 +934,7 @@ _push_operand (enum operand_type t, const void *ptr)
{
Object *obj = _get_object (t, ptr);
- if (current_stack_depth ==
- sizeof (current_object) / sizeof (current_object[0]))
+ if (current_stack_depth == ARRAY_LENGTH (current_object))
{
int n;
@@ -936,6 +957,7 @@ static void
_object_remove (Object *obj)
{
if (obj->operand != -1) {
+ ensure_operands (1);
if (obj->operand == current_stack_depth - 1) {
_trace_printf ("pop %% %s%ld destroyed\n",
obj->type->op_code, obj->token);