55
55
#undef dr_unregister_exit_event
56
56
#undef dr_register_post_attach_event
57
57
#undef dr_unregister_post_attach_event
58
+ #undef dr_register_pre_detach_event
59
+ #undef dr_unregister_pre_detach_event
58
60
#undef dr_register_thread_init_event
59
61
#undef dr_unregister_thread_init_event
60
62
#undef dr_register_thread_exit_event
@@ -144,6 +146,10 @@ typedef struct _generic_event_entry_t {
144
146
void (* cb_no_user_data )();
145
147
void (* cb_user_data )(void * );
146
148
} post_attach_cb ;
149
+ union {
150
+ void (* cb_no_user_data )();
151
+ void (* cb_user_data )(void * );
152
+ } pre_detach_cb ;
147
153
union {
148
154
void (* cb_no_user_data )(void * );
149
155
void (* cb_user_data )(void * , void * );
@@ -349,6 +355,8 @@ static void *exit_event_lock;
349
355
350
356
static cb_list_t cb_list_post_attach ;
351
357
static void * post_attach_event_lock ;
358
+ static cb_list_t cb_list_pre_detach ;
359
+ static void * pre_detach_event_lock ;
352
360
353
361
/* Thread event cbs and rwlock */
354
362
static cb_list_t cb_list_thread_init ;
@@ -414,6 +422,9 @@ drmgr_exit_event(void);
414
422
static void
415
423
drmgr_post_attach_event (void );
416
424
425
+ static void
426
+ drmgr_pre_detach_event (void );
427
+
417
428
static void
418
429
drmgr_thread_init_event (void * drcontext );
419
430
@@ -501,6 +512,7 @@ drmgr_init(void)
501
512
bb_cb_lock = dr_rwlock_create ();
502
513
exit_event_lock = dr_rwlock_create ();
503
514
post_attach_event_lock = dr_rwlock_create ();
515
+ pre_detach_event_lock = dr_rwlock_create ();
504
516
thread_event_lock = dr_rwlock_create ();
505
517
tls_lock = dr_mutex_create ();
506
518
cls_event_lock = dr_rwlock_create ();
@@ -523,6 +535,7 @@ drmgr_init(void)
523
535
524
536
dr_register_exit_event (drmgr_exit_event );
525
537
dr_register_post_attach_event (drmgr_post_attach_event );
538
+ dr_register_pre_detach_event (drmgr_pre_detach_event );
526
539
527
540
dr_register_thread_init_event (drmgr_thread_init_event );
528
541
dr_register_thread_exit_event (drmgr_thread_exit_event );
@@ -567,6 +580,7 @@ our_exit_event(void)
567
580
drmgr_event_exit ();
568
581
569
582
dr_unregister_post_attach_event (drmgr_post_attach_event );
583
+ dr_unregister_pre_detach_event (drmgr_pre_detach_event );
570
584
571
585
dr_unregister_thread_init_event (drmgr_thread_init_event );
572
586
dr_unregister_thread_exit_event (drmgr_thread_exit_event );
@@ -614,6 +628,7 @@ our_exit_event(void)
614
628
dr_rwlock_destroy (thread_event_lock );
615
629
dr_rwlock_destroy (exit_event_lock );
616
630
dr_rwlock_destroy (post_attach_event_lock );
631
+ dr_rwlock_destroy (pre_detach_event_lock );
617
632
dr_rwlock_destroy (bb_cb_lock );
618
633
619
634
dr_mutex_destroy (note_lock );
@@ -1955,6 +1970,7 @@ drmgr_event_init(void)
1955
1970
{
1956
1971
cblist_init (& cb_list_exit , sizeof (generic_event_entry_t ));
1957
1972
cblist_init (& cb_list_post_attach , sizeof (generic_event_entry_t ));
1973
+ cblist_init (& cb_list_pre_detach , sizeof (generic_event_entry_t ));
1958
1974
cblist_init (& cb_list_thread_init , sizeof (generic_event_entry_t ));
1959
1975
cblist_init (& cb_list_thread_exit , sizeof (generic_event_entry_t ));
1960
1976
cblist_init (& cblist_cls_init , sizeof (generic_event_entry_t ));
@@ -1986,6 +2002,7 @@ drmgr_event_exit(void)
1986
2002
*/
1987
2003
cblist_delete (& cb_list_exit );
1988
2004
cblist_delete (& cb_list_post_attach );
2005
+ cblist_delete (& cb_list_pre_detach );
1989
2006
cblist_delete (& cb_list_thread_init );
1990
2007
cblist_delete (& cb_list_thread_exit );
1991
2008
cblist_delete (& cblist_cls_init );
@@ -2130,6 +2147,65 @@ drmgr_post_attach_event(void)
2130
2147
cblist_delete_local (drcontext , & iter , BUFFER_SIZE_ELEMENTS (local ));
2131
2148
}
2132
2149
2150
+ DR_EXPORT
2151
+ bool
2152
+ drmgr_register_pre_detach_event (void (* func )(void ))
2153
+ {
2154
+ return drmgr_generic_event_add (& cb_list_pre_detach , pre_detach_event_lock , func , NULL ,
2155
+ false, NULL );
2156
+ }
2157
+
2158
+ DR_EXPORT
2159
+ bool
2160
+ drmgr_register_pre_detach_event_user_data (void (* func )(void * user_data ),
2161
+ drmgr_priority_t * priority , void * user_data )
2162
+ {
2163
+ return drmgr_generic_event_add (& cb_list_pre_detach , pre_detach_event_lock ,
2164
+ (void (* )(void ))func , priority , true, user_data );
2165
+ }
2166
+
2167
+ DR_EXPORT
2168
+ bool
2169
+ drmgr_unregister_pre_detach_event (void (* func )(void ))
2170
+ {
2171
+ return drmgr_generic_event_remove (& cb_list_pre_detach , pre_detach_event_lock ,
2172
+ (void (* )(void ))func );
2173
+ }
2174
+
2175
+ DR_EXPORT
2176
+ bool
2177
+ drmgr_unregister_pre_detach_event_user_data (void (* func )(void * user_data ))
2178
+ {
2179
+ return drmgr_generic_event_remove (& cb_list_pre_detach , pre_detach_event_lock ,
2180
+ (void (* )(void ))func );
2181
+ }
2182
+
2183
+ static void
2184
+ drmgr_pre_detach_event (void )
2185
+ {
2186
+ generic_event_entry_t local [EVENTS_STACK_SZ ];
2187
+ cb_list_t iter ;
2188
+ uint i ;
2189
+ void * drcontext = GLOBAL_DCONTEXT ;
2190
+ dr_rwlock_read_lock (pre_detach_event_lock );
2191
+ cblist_create_local (drcontext , & cb_list_pre_detach , & iter , (byte * )local ,
2192
+ BUFFER_SIZE_ELEMENTS (local ));
2193
+ dr_rwlock_read_unlock (pre_detach_event_lock );
2194
+
2195
+ for (i = 0 ; i < iter .num_def ; i ++ ) {
2196
+ if (!iter .cbs .generic [i ].pri .valid )
2197
+ continue ;
2198
+ bool is_using_user_data = iter .cbs .generic [i ].is_using_user_data ;
2199
+ void * user_data = iter .cbs .generic [i ].user_data ;
2200
+ if (is_using_user_data == false)
2201
+ (* iter .cbs .generic [i ].cb .pre_detach_cb .cb_no_user_data )();
2202
+ else {
2203
+ (* iter .cbs .generic [i ].cb .pre_detach_cb .cb_user_data )(user_data );
2204
+ }
2205
+ }
2206
+ cblist_delete_local (drcontext , & iter , BUFFER_SIZE_ELEMENTS (local ));
2207
+ }
2208
+
2133
2209
DR_EXPORT
2134
2210
bool
2135
2211
drmgr_register_thread_init_event (void (* func )(void * drcontext ))
0 commit comments