The last release of one of my modules works fine except in 5.6.2:

http://cpantesters.perl.org/show/Algorithm- Combinatorics.html#Algorithm-Combinatorics-0.22

A tester reported the failure and I can reproduce it in my Mac with 5.6.2.

The test suite runs OK but for the last two tests of a single subroutine (partitions_of_size_p), where Linux gives a segfault, and in my Mac I get a bus error. This only happens in 5.6.2, it does not happen in 5.8.x where the test suite passes.

I think it is unlikely that the function itself is buggy because the tests verify result sets of several thousands of elements in 5.8.x, so I wonder whether there's some XS gotcha behind this I am not aware of. The code is pretty simple, I attach it below not to check what it does, just to let you see whether you identify something that was different in 5.6.2 and could be the culprit.

-- fxn

#define UPDATE(av, i, n)   (SvIVX(AvARRAY(av)[i]) = n)
#define INCREMENT(av, i)   (++SvIVX(AvARRAY(av)[i]))
#define GETIV(av, i)       (SvIVX(AvARRAY(av)[i]))
#define GETAV(avptr)       ((AV*) SvRV(avptr))

int __next_partition_of_size_p(SV* k_avptr, SV* M_avptr, int p)
{
    AV* k = GETAV(k_avptr); /* follows notation in [3] */
    AV* M = GETAV(M_avptr); /* follows notation in [3] */
    int i, j;
    IV mi, x;
    I32 len_k, n_minus_p;

    len_k = av_len(k);
    for (i = len_k; i > 0; --i) {
        if (GETIV(k, i) < p-1 && GETIV(k, i) <= GETIV(M, i-1)) {
            INCREMENT(k, i);

            if (GETIV(k, i) > GETIV(M, i))
                UPDATE(M, i, GETIV(k, i));

            n_minus_p = len_k + 1 - p;
            mi = GETIV(M, i);
            x = n_minus_p + mi;
            for (j = i+1; j <= x; ++j) {
                UPDATE(k, j, 0);
                UPDATE(M, j, mi);
            }
            for (j = x+1; j <= len_k; ++j) {
                UPDATE(k, j, j - n_minus_p);
                UPDATE(M, j, j - n_minus_p);
            }
            return i;
        }
    }

    return -1;
}



Reply via email to