10
10
//
11
11
// ===----------------------------------------------------------------------===//
12
12
13
+ #include < alloca.h>
14
+
13
15
#include " sanitizer_common/sanitizer_common.h"
14
16
#include " sanitizer_common/sanitizer_libc.h"
15
17
#include " sanitizer_common/sanitizer_placement_new.h"
@@ -187,10 +189,8 @@ void ScopedReportBase::AddMemoryAccess(uptr addr, uptr external_tag, Shadow s,
187
189
mop->size = size;
188
190
mop->write = !(typ & kAccessRead );
189
191
mop->atomic = typ & kAccessAtomic ;
190
- mop->stack = SymbolizeStack (stack);
191
192
mop->external_tag = external_tag;
192
- if (mop->stack )
193
- mop->stack ->suppressable = true ;
193
+ mop->stack_trace = stack;
194
194
for (uptr i = 0 ; i < mset->Size (); i++) {
195
195
MutexSet::Desc d = mset->Get (i);
196
196
int id = this ->AddMutex (d.addr , d.stack_id );
@@ -199,6 +199,45 @@ void ScopedReportBase::AddMemoryAccess(uptr addr, uptr external_tag, Shadow s,
199
199
}
200
200
}
201
201
202
+ void ScopedReportBase::SymbolizeStackElems () {
203
+ // symbolize memory ops
204
+ for (usize i = 0 ; i < rep_->mops .Size (); i++) {
205
+ ReportMop *mop = rep_->mops [i];
206
+ mop->stack = SymbolizeStack (mop->stack_trace );
207
+ if (mop->stack )
208
+ mop->stack ->suppressable = true ;
209
+ }
210
+
211
+ // symbolize locations
212
+ for (usize i = 0 ; i < rep_->locs .Size (); i++) {
213
+ ReportLocation *loc = rep_->locs [i];
214
+ loc->stack = SymbolizeStackId (loc->stack_id );
215
+ }
216
+
217
+ for (usize i = 0 ; i < rep_->added_location_addrs .Size (); i++) {
218
+ if (ReportLocation *loc = SymbolizeData (rep_->added_location_addrs [i])) {
219
+ loc->suppressable = true ;
220
+ // TODO: These all end up at the back of locs - line them up with their
221
+ // corresponding location
222
+ rep_->locs .PushBack (loc);
223
+ }
224
+ }
225
+
226
+ // symbolize threads
227
+ for (usize i = 0 ; i < rep_->threads .Size (); i++) {
228
+ ReportThread *rt = rep_->threads [i];
229
+ rt->stack = SymbolizeStackId (rt->stack_id );
230
+ if (rt->stack )
231
+ rt->stack ->suppressable = rt->suppressable ;
232
+ }
233
+
234
+ // symbolize mutexes
235
+ for (usize i = 0 ; i < rep_->mutexes .Size (); i++) {
236
+ ReportMutex *rm = rep_->mutexes [i];
237
+ rm->stack = SymbolizeStackId (rm->stack_id );
238
+ }
239
+ }
240
+
202
241
void ScopedReportBase::AddUniqueTid (Tid unique_tid) {
203
242
rep_->unique_tids .PushBack (unique_tid);
204
243
}
@@ -216,10 +255,8 @@ void ScopedReportBase::AddThread(const ThreadContext *tctx, bool suppressable) {
216
255
rt->name = internal_strdup (tctx->name );
217
256
rt->parent_tid = tctx->parent_tid ;
218
257
rt->thread_type = tctx->thread_type ;
219
- rt->stack = 0 ;
220
- rt->stack = SymbolizeStackId (tctx->creation_stack_id );
221
- if (rt->stack )
222
- rt->stack ->suppressable = suppressable;
258
+ rt->stack_id = tctx->creation_stack_id ;
259
+ rt->suppressable = suppressable;
223
260
}
224
261
225
262
#if !SANITIZER_GO
@@ -270,7 +307,7 @@ int ScopedReportBase::AddMutex(uptr addr, StackID creation_stack_id) {
270
307
rep_->mutexes .PushBack (rm);
271
308
rm->id = rep_->mutexes .Size () - 1 ;
272
309
rm->addr = addr;
273
- rm->stack = SymbolizeStackId ( creation_stack_id) ;
310
+ rm->stack_id = creation_stack_id;
274
311
return rm->id ;
275
312
}
276
313
@@ -288,7 +325,7 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) {
288
325
loc->fd_closed = closed;
289
326
loc->fd = fd;
290
327
loc->tid = creat_tid;
291
- loc->stack = SymbolizeStackId ( creat_stack) ;
328
+ loc->stack_id = creat_stack;
292
329
rep_->locs .PushBack (loc);
293
330
AddThread (creat_tid);
294
331
return ;
@@ -310,7 +347,7 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) {
310
347
loc->heap_chunk_size = b->siz ;
311
348
loc->external_tag = b->tag ;
312
349
loc->tid = b->tid ;
313
- loc->stack = SymbolizeStackId ( b->stk ) ;
350
+ loc->stack_id = b->stk ;
314
351
rep_->locs .PushBack (loc);
315
352
AddThread (b->tid );
316
353
return ;
@@ -324,11 +361,7 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) {
324
361
AddThread (tctx);
325
362
}
326
363
#endif
327
- if (ReportLocation *loc = SymbolizeData (addr)) {
328
- loc->suppressable = true ;
329
- rep_->locs .PushBack (loc);
330
- return ;
331
- }
364
+ rep_->added_location_addrs .PushBack (addr);
332
365
}
333
366
334
367
#if !SANITIZER_GO
@@ -761,65 +794,91 @@ void ReportRace(ThreadState *thr, RawShadow *shadow_mem, Shadow cur, Shadow old,
761
794
DynamicMutexSet mset1;
762
795
MutexSet *mset[kMop ] = {&thr->mset , mset1};
763
796
764
- // We need to lock the slot during RestoreStack because it protects
765
- // the slot journal.
766
- Lock slot_lock (&ctx->slots [static_cast <uptr>(s[1 ].sid ())].mtx );
767
- ThreadRegistryLock l0 (&ctx->thread_registry );
768
- Lock slots_lock (&ctx->slot_mtx );
769
- if (SpuriousRace (old))
770
- return ;
771
- if (!RestoreStack (EventType::kAccessExt , s[1 ].sid (), s[1 ].epoch (), addr1,
772
- size1, typ1, &tids[1 ], &traces[1 ], mset[1 ], &tags[1 ])) {
773
- StoreShadow (&ctx->last_spurious_race , old.raw ());
774
- return ;
775
- }
797
+ #if SANITIZER_APPLE
798
+ static Mutex report_write_mutex;
799
+ Lock report_write_lock (&report_write_mutex);
800
+ ScopedReport *_rep = (ScopedReport *)alloca (sizeof (ScopedReport));
801
+ #endif
802
+ // Take a new scope as Apple platforms need to release the below locks,
803
+ // before writing out the report, in order to avoid a deadlock
804
+ {
805
+ // We need to lock the slot during RestoreStack because it protects
806
+ // the slot journal.
807
+ Lock slot_lock (&ctx->slots [static_cast <uptr>(s[1 ].sid ())].mtx );
808
+ ThreadRegistryLock l0 (&ctx->thread_registry );
809
+ Lock slots_lock (&ctx->slot_mtx );
810
+ if (SpuriousRace (old))
811
+ return ;
812
+ if (!RestoreStack (EventType::kAccessExt , s[1 ].sid (), s[1 ].epoch (), addr1,
813
+ size1, typ1, &tids[1 ], &traces[1 ], mset[1 ], &tags[1 ])) {
814
+ StoreShadow (&ctx->last_spurious_race , old.raw ());
815
+ return ;
816
+ }
776
817
777
- if (IsFiredSuppression (ctx, rep_typ, traces[1 ]))
778
- return ;
818
+ if (IsFiredSuppression (ctx, rep_typ, traces[1 ]))
819
+ return ;
779
820
780
- if (HandleRacyStacks (thr, traces))
781
- return ;
821
+ if (HandleRacyStacks (thr, traces))
822
+ return ;
782
823
783
- // If any of the accesses has a tag, treat this as an "external" race.
784
- uptr tag = kExternalTagNone ;
785
- for (uptr i = 0 ; i < kMop ; i++) {
786
- if (tags[i] != kExternalTagNone ) {
787
- rep_typ = ReportTypeExternalRace;
788
- tag = tags[i];
789
- break ;
824
+ // If any of the accesses has a tag, treat this as an "external" race.
825
+ uptr tag = kExternalTagNone ;
826
+ for (uptr i = 0 ; i < kMop ; i++) {
827
+ if (tags[i] != kExternalTagNone ) {
828
+ rep_typ = ReportTypeExternalRace;
829
+ tag = tags[i];
830
+ break ;
831
+ }
790
832
}
791
- }
792
833
793
- ScopedReport rep (rep_typ, tag);
794
- for (uptr i = 0 ; i < kMop ; i++)
795
- rep.AddMemoryAccess (addr, tags[i], s[i], tids[i], traces[i], mset[i]);
834
+ #if SANITIZER_APPLE
835
+ new (_rep) ScopedReport (rep_typ, tag);
836
+ ScopedReport &rep = *_rep;
837
+ #else
838
+ ScopedReport rep (rep_typ, tag);
839
+ #endif
840
+ for (uptr i = 0 ; i < kMop ; i++)
841
+ rep.AddMemoryAccess (addr, tags[i], s[i], tids[i], traces[i], mset[i]);
796
842
797
- for (uptr i = 0 ; i < kMop ; i++) {
798
- ThreadContext *tctx = static_cast <ThreadContext *>(
799
- ctx->thread_registry .GetThreadLocked (tids[i]));
800
- rep.AddThread (tctx);
801
- }
843
+ for (uptr i = 0 ; i < kMop ; i++) {
844
+ ThreadContext *tctx = static_cast <ThreadContext *>(
845
+ ctx->thread_registry .GetThreadLocked (tids[i]));
846
+ rep.AddThread (tctx);
847
+ }
802
848
803
- rep.AddLocation (addr_min, addr_max - addr_min);
804
-
805
- if (flags ()->print_full_thread_history ) {
806
- const ReportDesc *rep_desc = rep.GetReport ();
807
- for (uptr i = 0 ; i < rep_desc->threads .Size (); i++) {
808
- Tid parent_tid = rep_desc->threads [i]->parent_tid ;
809
- if (parent_tid == kMainTid || parent_tid == kInvalidTid )
810
- continue ;
811
- ThreadContext *parent_tctx = static_cast <ThreadContext *>(
812
- ctx->thread_registry .GetThreadLocked (parent_tid));
813
- rep.AddThread (parent_tctx);
849
+ rep.AddLocation (addr_min, addr_max - addr_min);
850
+
851
+ if (flags ()->print_full_thread_history ) {
852
+ const ReportDesc *rep_desc = rep.GetReport ();
853
+ for (uptr i = 0 ; i < rep_desc->threads .Size (); i++) {
854
+ Tid parent_tid = rep_desc->threads [i]->parent_tid ;
855
+ if (parent_tid == kMainTid || parent_tid == kInvalidTid )
856
+ continue ;
857
+ ThreadContext *parent_tctx = static_cast <ThreadContext *>(
858
+ ctx->thread_registry .GetThreadLocked (parent_tid));
859
+ rep.AddThread (parent_tctx);
860
+ }
814
861
}
815
- }
816
862
817
863
#if !SANITIZER_GO
818
- if (!((typ0 | typ1) & kAccessFree ) &&
819
- s[1 ].epoch () <= thr->last_sleep_clock .Get (s[1 ].sid ()))
820
- rep.AddSleep (thr->last_sleep_stack_id );
864
+ if (!((typ0 | typ1) & kAccessFree ) &&
865
+ s[1 ].epoch () <= thr->last_sleep_clock .Get (s[1 ].sid ()))
866
+ rep.AddSleep (thr->last_sleep_stack_id );
867
+ #endif
868
+
869
+ #if SANITIZER_APPLE
870
+ } // Close this scope to release the locks
871
+
872
+ _rep->SymbolizeStackElems ();
873
+ OutputReport (thr, *_rep);
874
+
875
+ // Need to manually destroy this because we used placement new to allocate
876
+ _rep->~ScopedReport ();
877
+ #else
878
+ rep.SymbolizeStackElems ();
879
+ OutputReport (thr, rep);
880
+ }
821
881
#endif
822
- OutputReport (thr, rep);
823
882
}
824
883
825
884
void PrintCurrentStack (ThreadState *thr, uptr pc) {
0 commit comments