Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposed fix for possible qsort callback random return value #139

Merged
merged 1 commit into from
May 25, 2018

Conversation

nawrockie
Copy link
Member

@nawrockie nawrockie commented May 23, 2018

Issue #11 in Infernal (EddyRivasLab/infernal#11) highlights the possibility of random return values from the hit_sorter* functions used by qsort when all compared keys are equal. This branch fixes analogous situations in hmmer's develop (h3) branch. Please take a look at the comparison.

There are two qsort helper functions that I did not edit. These are: cachedb.c:sort_seq() and hmmdmstr.c:hit_sorter(). Those use a different strategy that I think is 'ok' with respect to this issue of possible random return values, but see what you think. For example, cachedb:sort_seq() is:

static int
sort_seq(const void *p1, const void *p2)
{
  int cmp;

  cmp  = (((HMMER_SEQ *)p1)->idx < ((HMMER_SEQ *)p2)->idx);
  cmp -= (((HMMER_SEQ *)p1)->idx > ((HMMER_SEQ *)p2)->idx);

  return cmp;
}

Same strategy is used by hmmdmstr.c:hit_sorter().

I think that covers all qsort() helper functions.

I did not update BUGTRAX because I could not find it (no Bugs/ subdir?). Here is what I would have put as the entry if I had found it, based on Infernal's BUGTRAX i48 entry that I just wrote:

ID              ?
TITLE           qsort callback random return value
STATUS          CLOSED
XREF            /panfs/pan1/infernal/notebook/18_0521_inf_qsort_helpers_bug/infernal
                (NCBI)
REPORTED_BY     Yuri Gribov (github username: yugr)
                https://github.com/EddyRivasLab/infernal/issues/11
CLOSED_DATE     EPN, Wed May 23 09:07:57 2018
DESCRIPTION

Some of the functions used by qsort() to sort (fm_ssv.c:FM_hit_sorter(),
hmmerfm-exactmatch.c:hit_sorter(), p7_tophits.c:hit_sorter_by_sortkey(),
p7_tophits.c:hit_sorter_by_seqidx_aliposition(), and
p7_tophits.c:hit_sorter_by_modelname_aliposition()), were not
returning value '0' for input in which all compared fields for the two
objects being compared were equal. Instead, 1 or -1 was being returned,
in ways that Yuri explained 'may return random result when input
structs have all compared fields equal. This in turn may causes
inconsistent order or even crashes in some qsort implementations.' The
fix, as Yuri suggested was simply to update the final comparison so
that '0' is returned if all fields are equal, that is if both '<' and
'>' comparisons of final field checked (and all other fields checked)
returns false.

…equal in qsort sort routines, does not change sort routines cachedb.c:sort_seq and hmmdmstr.c:hit_sorter() which use different strategies I am not sure about.
@cryptogenomicon cryptogenomicon merged commit be2e44c into develop May 25, 2018
@cryptogenomicon cryptogenomicon deleted the qsortfix branch May 25, 2018 12:00
@cryptogenomicon
Copy link
Member

good, thanks!

cryptogenomicon added a commit that referenced this pull request Nov 7, 2018
A qsort() helper function needs to return 0 when its keys are
equal. We had multiple places where qsort helpers are only returning
-1/1. First reported in EddyRivasLab/infernal#11 by Yuri Gribov
(yugr), author of SortCheck. In May 2018, EPN committed Infernal
fixes, and sent a pull request (#139) with H3 fixes. Belatedly, here
are the analogous H4 fixes.

Also, adds -L flag to the find's in makeTAGS.sh, so the TAGS file
includes lib/easel when that's a symlink.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants