On Sat, 27 May 2000, Mark Taylor wrote:

> The problem is gfc->cw_lower_index.  It is set to 6, and is never
> changed.  Yet it has been changed to -1001465578, so there is
> I would start by putting print statements in lame_encode_frame(),
> and see if you can narrow down in which major block
> of code cw_lower_limit is overwritten (psycho acoustics, MDCTs,
> outer_loop or format_bitstream?  

The value is changed during L3psycho_anal in psymodel.c. I put lots of
assertions in the channel loop (a very long loop really!) and the value
was changed before the end of the loop:

---8<---
assert(gfc->cw_lower_index == 6); /***** line 865 *****/

    /* threshold calculation for short blocks */
    for (sblock = 0; sblock < 3; sblock++) {
        j = 0;
        for (b = 0; b < gfc->npart_s_orig; b++) {
            int i;
            FLOAT ecb;
            ecb = gfc->energy_s[sblock][j++];
            for (i = gfc->numlines_s[b]; i > 0; i--) {
                ecb += gfc->energy_s[sblock][j++];
            }
            eb[b] = ecb;
        }

        for (b = 0; b < gfc->npart_s; b++) {
            FLOAT8 ecb;
            ecb = 0;
            for (k = gfc->s3ind_s[b][0]; k <= gfc->s3ind_s[b][1]; k++) {
                ecb += gfc->s3_s[b][k] * eb[k];
            }
            thr[b] = Max(1e-6, ecb);
        }

        for (sb = 0; sb < SBPSY_s; sb++) {
            FLOAT8 enn, thmm;
            enn  = gfc->w1_s[sb] * eb[gfc->bu_s[sb]] + gfc->w2_s[sb] *
eb[gfc->bo_s[sb]];
            thmm = gfc->w1_s[sb] *thr[gfc->bu_s[sb]] + gfc->w2_s[sb] *
thr[gfc->bo_s[sb]];
            for (b = gfc->bu_s[sb]+1; b < gfc->bo_s[sb]; b++) {
                enn  += eb[b];
                thmm += thr[b];
            }
/*
printf("&gfc->cw_lower_index = 0x%08x\n", &gfc->cw_lower_index);
printf("&gfc->en[chn].s[sb][sblock] = 0x%08x\n",
&gfc->en[chn].s[sb][sblock]);
printf("&gfc->thm[chn].s[sb][sblock] = 0x%08x\n",
&gfc->thm[chn].s[sb][sblock]);
*/
            gfc->en[chn].s[sb][sblock] = enn;
            gfc->thm[chn].s[sb][sblock] = thmm;
        }
#if 0 /***** line 905 *****/
assert(gfc->cw_lower_index == 6);
#endif
    }
assert(gfc->cw_lower_index == 6); /***** line 909 *****/
  } /* end loop over chn */

assert(gfc->cw_lower_index == 6);
---8<---

The result:

Assertion (gfc->cw_lower_index == 6) failed in file psymodel.c at line 909

On line 865 the assert condition is still true.

Note that the line numbers in my version are very different from the
original version, because I have lots of assertions added before these 
ones.

But if I change the #if on line 905 to #if 1, the problem disappears and
lame seems to work ok. So it's quite difficult to track it down more
precisely. But I expect that it could be those gfc->en or gfc->thm that
could be accessed out of bounds.

Adding char dummy[1000]; to util.h before the variable cw_lower_index also
removes the problem. I could continue trying to use smaller values like
dummy[4] or dummy[8] to find out how much of the information is
overwritten and try to change the order or the variables in the structure
to find out which one causes the problem.

Someone who knows about this function could look into this more carefully
and maybe insert some assertions to check the bounds... oh, I might try to
use bounds-checking version of gcc to compile this on Alpha... too bad,
that I don't have (and there probably isn't available) a bounds-checking
version of gcc for AmigaOS and PPC. Has anyone else tried to compile and
run lame using bounds-checking?

Or then it could be of course something else. Once I really had a big
problem debugging a software. In the debugger, it worked it I
single-stepped the routine to a certain point but it failed if I
single-stepped one step less. And the code was fine and finally I managed
to track down a processor bug on 68060 (too bad that it was already a
documented one, i.e. a "feature"). :( It behaved the similar way,
disappeared when the order of instructions was changed. I don't have any
debugging tool for PPC and if I had, I had to learn first how to use that
anyway... :)

But I guess that in this case, this is just a bug in the software. The
function is very long, a way too long in my opinion, and because it wasn't
well indented, I had a little difficulties trying to find the end of that
channel for loop. Would it be a nice idea to break it into smaller
functions? Or does it make it that much slower? Compilers should be able
to inline those parts anyway...?

Kimmo

--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )

Reply via email to