Closed Bug 957458 Opened 12 years ago Closed 12 years ago

_PR_UNSET_THREAD_RWLOCK_RANK decrements |index| incorrectly in the while loop

Categories

(NSPR :: NSPR, defect, P1)

defect

Tracking

(Not tracked)

RESOLVED FIXED
4.10.3

People

(Reporter: wtc, Assigned: wtc)

Details

Attachments

(3 files, 4 obsolete files)

Attached patch Patch (obsolete) — Splinter Review
_PR_UNSET_THREAD_RWLOCK_RANK has a while loop: index = lock_stack->trs_index - 1; while (index-- >= 0) { if ((lock_stack->trs_stack[index] == rwlock) && !done) { ... The intention of the code is to decrement |index| at the end of the loop body, but the loop body actually uses the decremented value of |index|. The patch changes the while loop to a for loop so that we can decrement |index| at the right time. It also makes the following changes. 1. _PR_SET_THREAD_RWLOCK_RANK and _PR_UNSET_THREAD_RWLOCK_RANK are called only when rwlock->rw_rank is not PR_RWLOCK_RANK_NONE. It is incorrect to add a lock with PR_RWLOCK_RANK_NONE to the thread's lock stack. 2. In two if statements, perform the cheaper test before the more expensive test.
Attachment #8356949 - Flags: review?(kaie)
Attached patch Patch v1.1 (obsolete) — Splinter Review
Use TAB characters, following the prevalent style in the file.
Attachment #8356949 - Attachment is obsolete: true
Attachment #8356949 - Flags: review?(kaie)
Attachment #8356952 - Flags: review?(kaie)
Comment on attachment 8356952 [details] [diff] [review] Patch v1.1 r=kaie
Attachment #8356952 - Flags: review?(kaie) → review+
Attached patch Patch v2 (obsolete) — Splinter Review
I found that _PR_GET_THREAD_RWLOCK_RANK has a serious bug: it also needs to return PR_RWLOCK_RANK_NONE when lock_stack exists but is empty (lock_stack->trs_index == 0). This bug implies either no NSPR users are using a PRRWLock with a nonzero lock rank, or none of those NSPR users are using debug builds of NSPR. So we can also consider just removing the lock rank checking code, and changing PR_NewRWLock to assert that lock_rank == PR_RWLOCK_RANK_NONE. I changed the patch to also fix this bug.
Attachment #8356952 - Attachment is obsolete: true
Attachment #8357338 - Flags: review?(kaie)
Attached patch Add a rwlockrank.c test (obsolete) — Splinter Review
Attachment #8357340 - Flags: review?(kaie)
This patch fixes a printf format problem I noticed in rwlocktest.c.
Attachment #8357348 - Flags: review?(kaie)
Comment on attachment 8357338 [details] [diff] [review] Patch v2 Review of attachment 8357338 [details] [diff] [review]: ----------------------------------------------------------------- I single-stepped the relevant code in the debugger and verified it does the right thing now. I think I can implement the lock stack in a more efficient way, but since this is just debugging code and one of the bugs implies nobody has ever used it, I don't want to spend more time on this.
Attachment #8357338 - Flags: superreview?(brian)
Comment on attachment 8357338 [details] [diff] [review] Patch v2 r=kaie You might consider to write the code in a simpler way, to make it more readable, and I'm always worried by statements that combine comparisons and assignements (your statement is right, but it requires more time to read such statements to convince oneself it is correct). Instead of: if ((lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key)) == NULL || lock_stack->trs_index == 0) I'd use: lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key); if (!lock_stack || !lock_stack->trs_index)
Attachment #8357338 - Flags: review?(kaie) → review+
Attachment #8357348 - Flags: review?(kaie) → review+
Comment on attachment 8357340 [details] [diff] [review] Add a rwlockrank.c test Why do you destroy only one of the locks?
Attachment #8357340 - Flags: review?(kaie) → review+
Attached patch Patch v3Splinter Review
Kai, I made the change you suggested. Thanks! Patch checked in: https://hg.mozilla.org/projects/nspr/rev/88cdc3e565e5
Attachment #8357338 - Attachment is obsolete: true
Attachment #8357338 - Flags: superreview?(brian)
Attachment #8360752 - Flags: checked-in+
Comment on attachment 8357348 [details] [diff] [review] Print a pointer using the %p format specifier Review of attachment 8357348 [details] [diff] [review]: ----------------------------------------------------------------- Patch checked in: https://hg.mozilla.org/projects/nspr/rev/b6674f2a3776
Attachment #8357348 - Flags: checked-in+
Kai, thank you for catching the missing PR_DestroyRWLock calls. Patch checked in: https://hg.mozilla.org/projects/nspr/rev/518d6d014628
Attachment #8357340 - Attachment is obsolete: true
Attachment #8360756 - Flags: checked-in+
Status: ASSIGNED → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: