@@ -94,6 +94,7 @@ int pkru_offset(void) {
94
94
* logging thread pops but there's not much benefit to this for debugging.
95
95
*/
96
96
#define QUEUE_SIZE 8192
97
+ #define MAX_STACKTRACE 10
97
98
98
99
// The entries in the queue
99
100
typedef struct mpk_err {
@@ -103,6 +104,7 @@ typedef struct mpk_err {
103
104
uint64_t sp ;
104
105
uint64_t fp ;
105
106
uint32_t pkru ;
107
+ uint64_t ret_addrs [MAX_STACKTRACE ];
106
108
} mpk_err ;
107
109
108
110
struct queue {
@@ -196,7 +198,24 @@ void permissive_mode_handler(int sig, siginfo_t *info, void *ctxt) {
196
198
struct queue * q = get_queue ();
197
199
uint64_t val ;
198
200
memcpy (& val , info -> si_addr , sizeof (uint64_t ));
199
- mpk_err err = {.addr = (uint64_t )info -> si_addr , .val = val , .pc = pc , .sp = sp , .fp = fp , .pkru = old_pkru };
201
+ mpk_err err = {
202
+ .addr = (uint64_t )info -> si_addr ,
203
+ .val = val ,
204
+ .pc = pc ,
205
+ .sp = sp ,
206
+ .fp = fp ,
207
+ .pkru = old_pkru
208
+ };
209
+ for (int i = 0 ; i < MAX_STACKTRACE ; i ++ ) {
210
+ // I thought the stopping condition was fp == 0 but it seems to be 1 so
211
+ // just stop at any obviously bad address
212
+ if (fp < PAGE_SIZE ) {
213
+ break ;
214
+ }
215
+ uint64_t ra = * (uint64_t * )(fp + 8 );
216
+ err .ret_addrs [i ] = ra ;
217
+ fp = * (uint64_t * )fp ;
218
+ }
200
219
push_queue (q , err );
201
220
release_queue (q );
202
221
} else if (handling_trap ) {
@@ -368,6 +387,25 @@ void flush_queue(FILE *log) {
368
387
print_address (log , "sp" , (void * )err .sp );
369
388
print_address (log , "fp" , (void * )err .fp );
370
389
fprintf (log , "pkru: %x\n" , err .pkru );
390
+
391
+ Dl_info dlinf = { 0 };
392
+ const char * fn_name = "??" ;
393
+ if (dladdr ((void * )err .pc , & dlinf ) != 0 ) {
394
+ fn_name = dlinf .dli_sname ;
395
+ }
396
+ fprintf (log , "#0 %p in %s ()\n" , (void * )err .pc , fn_name );
397
+ for (int i = 0 ; i < MAX_STACKTRACE ; i ++ ) {
398
+ void * ra = (void * )err .ret_addrs [i ];
399
+ if (ra == NULL ) {
400
+ break ;
401
+ }
402
+ if (dladdr (ra , & dlinf ) != 0 ) {
403
+ fn_name = dlinf .dli_sname ;
404
+ } else {
405
+ fn_name = "??" ;
406
+ }
407
+ fprintf (log , "#%d %p in %s ()\n" , i + 1 , ra , fn_name );
408
+ }
371
409
}
372
410
release_queue (q );
373
411
}
0 commit comments