diff options
author | M Joonas Pihlaja <jpihlaja@cc.helsinki.fi> | 2009-07-24 07:42:57 +0300 |
---|---|---|
committer | M Joonas Pihlaja <jpihlaja@cc.helsinki.fi> | 2009-09-02 04:50:20 +0100 |
commit | 174c2620c82a47d067ec7b5062a4f513155a0b1f (patch) | |
tree | 461ec12fa1f16094bca6ad956ac29b44c95f763e | |
parent | bb480d235882d8e7d5748a3837f9b274a8b8ac86 (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.
-rw-r--r-- | util/cairo-trace/trace.c | 26 |
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); |