Changeset 6071


Ignore:
Timestamp:
Mar 20, 2007, 3:55:15 AM (13 years ago)
Author:
gb
Message:

If we can't take a signal on a thread-specific altstack, handle the
case where a signal handler might want to run on the lisp stack and
switch to the foreign stack in that case.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/objc-gf/ccl/lisp-kernel/x86-exceptions.c

    r6030 r6071  
    10391039
    10401040void
    1041 altstack_signal_handler(int signum, siginfo_t *info, ExceptionInformation  *context)
    1042 {
    1043   TCR* tcr = get_tcr(true);
    1044   LispObj *foreign_rsp = find_foreign_rsp(xpGPR(context,Isp), tcr->cs_area, tcr);
    1045 #if 1
    1046   if (tcr->valence != TCR_STATE_LISP) {
    1047     Bug(context, "exception in foreign context");
    1048   }
    1049 #endif
     1041handle_signal_on_foreign_stack(TCR *tcr,
     1042                               void *handler,
     1043                               int signum,
     1044                               siginfo_t *info,
     1045                               ExceptionInformation *context,
     1046                               LispObj return_address
     1047#ifdef DARWIN_GS_HACK
     1048                               , Boolean gs_was_tcr
     1049#endif
     1050                               )
     1051{
    10501052#ifdef LINUX
    10511053  fpregset_t fpregs = NULL;
     
    10531055  void *fpregs = NULL;
    10541056#endif
     1057#ifdef DARWIN
     1058  MCONTEXT_T mcontextp = NULL;
     1059#endif
    10551060  siginfo_t *info_copy = NULL;
    10561061  ExceptionInformation *xp = NULL;
    1057 
    1058   if (foreign_rsp) {
     1062  LispObj *foreign_rsp = find_foreign_rsp(xpGPR(context,Isp), tcr->cs_area, tcr);
     1063
    10591064#ifdef LINUX
    1060     foreign_rsp = copy_fpregs(context, foreign_rsp, &fpregs);
    1061 #endif
    1062     foreign_rsp = copy_siginfo(info, foreign_rsp);
    1063     info_copy = (siginfo_t *)foreign_rsp;
    1064     foreign_rsp = copy_ucontext(context, foreign_rsp, fpregs);
    1065     xp = (ExceptionInformation *)foreign_rsp;
    1066     *--foreign_rsp = (LispObj)__builtin_return_address(0);
    1067     switch_to_foreign_stack(foreign_rsp,signal_handler,signum,info_copy,xp);
    1068   }
     1065  foreign_rsp = copy_fpregs(context, foreign_rsp, &fpregs);
     1066#endif
     1067#ifdef DARWIN
     1068  foreign_rsp = copy_darwin_mcontext(UC_MCONTEXT(context), foreign_rsp, &mcontextp);
     1069#endif
     1070  foreign_rsp = copy_siginfo(info, foreign_rsp);
     1071  info_copy = (siginfo_t *)foreign_rsp;
     1072  foreign_rsp = copy_ucontext(context, foreign_rsp, fpregs);
     1073  xp = (ExceptionInformation *)foreign_rsp;
     1074#ifdef DARWIN
     1075  UC_MCONTEXT(xp) = mcontextp;
     1076#endif
     1077  *--foreign_rsp = return_address;
     1078#ifdef DARWIN_GS_HACK
     1079  if (gs_was_tcr) {
     1080    set_gs_address(tcr);
     1081  }
     1082#endif
     1083  switch_to_foreign_stack(foreign_rsp,handler,signum,info_copy,xp);
     1084}
     1085
     1086
     1087void
     1088altstack_signal_handler(int signum, siginfo_t *info, ExceptionInformation  *context)
     1089{
     1090  TCR* tcr = get_tcr(true);
     1091#if 1
     1092  if (tcr->valence != TCR_STATE_LISP) {
     1093    Bug(context, "exception in foreign context");
     1094  }
     1095#endif
     1096  handle_signal_on_foreign_stack(tcr,signal_handler,signum,info,context,(LispObj)__builtin_return_address(0), false);
    10691097}
    10701098
     
    11101138        handle_exception(signum, info, context, tcr);
    11111139        if (alloc_displacement) {
    1112           fprintf(stderr, "tcr = 0x%x, allocptr = 0x%lx, disp = %d\n",tcr,tcr->save_allocptr,alloc_displacement);
    11131140          tcr->save_allocptr -= alloc_displacement;
    11141141        }
     
    11351162}
    11361163
    1137 void
    1138 altstack_interrupt_handler (int signum, siginfo_t *info, ExceptionInformation *context)
     1164#ifndef USE_SIGALTSTACK
     1165void
     1166arbstack_interrupt_handler (int signum, siginfo_t *info, ExceptionInformation *context)
    11391167{
    11401168#ifdef DARWIN_GS_HACK
     
    11421170#endif
    11431171  TCR *tcr = get_interrupt_tcr(false);
    1144   LispObj *foreign_rsp = find_foreign_rsp(xpGPR(context,Isp), tcr->cs_area, tcr);
    1145 #ifdef LINUX
    1146   fpregset_t fpregs = NULL;
    1147 #else
    1148   void *fpregs = NULL;
    1149 #endif
    1150 #ifdef DARWIN
    1151   MCONTEXT_T mcontextp = NULL;
    1152 #endif
    1153   siginfo_t *info_copy = NULL;
    1154   ExceptionInformation *xp = NULL;
    1155 
    1156   if (foreign_rsp) {
    1157 #ifdef LINUX
    1158     foreign_rsp = copy_fpregs(context, foreign_rsp, &fpregs);
    1159 #endif
    1160 #ifdef DARWIN
    1161     foreign_rsp = copy_darwin_mcontext(UC_MCONTEXT(context), foreign_rsp, &mcontextp);
    1162 #endif
    1163     foreign_rsp = copy_siginfo(info, foreign_rsp);
    1164     info_copy = (siginfo_t *)foreign_rsp;
    1165     foreign_rsp = copy_ucontext(context, foreign_rsp, fpregs);
    1166     xp = (ExceptionInformation *)foreign_rsp;
    1167 #ifdef DARWIN
    1168     UC_MCONTEXT(xp) = mcontextp;
    1169 #endif
    1170     *--foreign_rsp = (LispObj)__builtin_return_address(0);
     1172  area *vs = tcr->vs_area;
     1173  BytePtr current_sp = (BytePtr) current_stack_pointer();
     1174
     1175  if ((current_sp >= vs->low) &&
     1176      (current_sp < vs->high)) {
     1177    handle_signal_on_foreign_stack(tcr,
     1178                                   interrupt_handler,
     1179                                   signum,
     1180                                   info,
     1181                                   context,
     1182                                   (LispObj)__builtin_return_address(0)
     1183#ifdef DARWIN_GS_HACK
     1184                                   ,gs_was_tcr
     1185#endif
     1186                                   );
     1187  } else {
     1188    /* If we're not on the value stack, we pretty much have to be on
     1189       the C stack.  Just run the handler. */
    11711190#ifdef DARWIN_GS_HACK
    11721191    if (gs_was_tcr) {
     
    11741193    }
    11751194#endif
    1176     switch_to_foreign_stack(foreign_rsp,interrupt_handler,signum,info_copy,xp);
    1177   }
    1178 }
     1195    interrupt_handler(signum, info, context);
     1196  }
     1197}
     1198
     1199#else /* altstack works */
     1200 
     1201void
     1202altstack_interrupt_handler (int signum, siginfo_t *info, ExceptionInformation *context)
     1203{
     1204#ifdef DARWIN_GS_HACK
     1205  Boolean gs_was_tcr = ensure_gs_pthread();
     1206#endif
     1207  TCR *tcr = get_interrupt_tcr(false);
     1208  handle_signal_on_foreign_stack(tcr,interrupt_handler,signum,info,context,(LispObj)__builtin_return_address(0)
     1209#ifdef DARWIN_GS_HACK
     1210                                 ,gs_was_tcr
     1211#endif
     1212                                 );
     1213}
     1214
     1215#endif
    11791216
    11801217
     
    11961233  sa.sa_flags =
    11971234    SA_RESTART
     1235#ifdef USE_SIGALTSTACK
    11981236    | SA_ONSTACK
     1237#endif
    11991238    | SA_SIGINFO;
    12001239
     
    12221261 
    12231262  install_signal_handler(SIGNAL_FOR_PROCESS_INTERRUPT,
    1224                          altstack_interrupt_handler);
     1263#ifdef USE_SIGALTSTACK
     1264                         altstack_interrupt_handler
     1265#else
     1266                         arbstack_interrupt_handler
     1267#endif
     1268);
    12251269  signal(SIGPIPE, SIG_IGN);
    12261270}
    12271271
    1228 
    1229 void
    1230 altstack_suspend_resume_handler(int signum, siginfo_t *info, ExceptionInformation  *context)
     1272#ifndef USE_SIGALTSTACK
     1273void
     1274arbstack_suspend_resume_handler(int signum, siginfo_t *info, ExceptionInformation  *context)
    12311275{
    12321276#ifdef DARWIN_GS_HACK
    12331277  Boolean gs_was_tcr = ensure_gs_pthread();
    12341278#endif
    1235   TCR* tcr = get_tcr(true);
    1236   LispObj *foreign_rsp = find_foreign_rsp(xpGPR(context,Isp), tcr->cs_area, tcr);
    1237 #ifdef LINUX
    1238   fpregset_t fpregs = NULL;
    1239 #else
    1240   void *fpregs = NULL;
    1241 #endif
    1242 #ifdef DARWIN
    1243   MCONTEXT_T mcontextp = NULL;
    1244 #endif
    1245 
    1246   siginfo_t *info_copy = NULL;
    1247   ExceptionInformation *xp = NULL;
    1248 
    1249   if (foreign_rsp) {
    1250 #ifdef LINUX
    1251     foreign_rsp = copy_fpregs(context, foreign_rsp, &fpregs);
    1252 #endif
    1253 #ifdef DARWIN
    1254     foreign_rsp = copy_darwin_mcontext(UC_MCONTEXT(context), foreign_rsp, &mcontextp);
    1255 #endif
    1256     foreign_rsp = copy_siginfo(info, foreign_rsp);
    1257     info_copy = (siginfo_t *)foreign_rsp;
    1258     foreign_rsp = copy_ucontext(context, foreign_rsp, fpregs);
    1259     xp = (ExceptionInformation *)foreign_rsp;
    1260 #ifdef DARWIN
    1261     UC_MCONTEXT(xp) = mcontextp;
    1262 #endif
    1263     *--foreign_rsp = (LispObj)__builtin_return_address(0);
     1279  TCR *tcr = get_interrupt_tcr(false);
     1280  area *vs = tcr->vs_area;
     1281  BytePtr current_sp = (BytePtr) current_stack_pointer();
     1282
     1283  if ((current_sp >= vs->low) &&
     1284      (current_sp < vs->high)) {
     1285    handle_signal_on_foreign_stack(tcr,
     1286                                   suspend_resume_handler,
     1287                                   signum,
     1288                                   info,
     1289                                   context,
     1290                                   (LispObj)__builtin_return_address(0)
     1291#ifdef DARWIN_GS_HACK
     1292                                   ,gs_was_tcr
     1293#endif
     1294                                   );
     1295  } else {
     1296    /* If we're not on the value stack, we pretty much have to be on
     1297       the C stack.  Just run the handler. */
    12641298#ifdef DARWIN_GS_HACK
    12651299    if (gs_was_tcr) {
     
    12671301    }
    12681302#endif
    1269     switch_to_foreign_stack(foreign_rsp,suspend_resume_handler,signum,info_copy,xp);
    1270   }
    1271 }
    1272 
    1273 void
    1274 quit_handler(int signum, siginfo_t info, ExceptionInformation *xp)
     1303    suspend_resume_handler(signum, info, context);
     1304  }
     1305}
     1306
     1307
     1308#else /* altstack works */
     1309void
     1310altstack_suspend_resume_handler(int signum, siginfo_t *info, ExceptionInformation  *context)
     1311{
     1312#ifdef DARWIN_GS_HACK
     1313  Boolean gs_was_tcr = ensure_gs_pthread();
     1314#endif
     1315  TCR* tcr = get_tcr(true);
     1316  handle_signal_on_foreign_stack(tcr,
     1317                                 suspend_resume_handler,
     1318                                 signum,
     1319                                 info,
     1320                                 context,
     1321                                 (LispObj)__builtin_return_address(0)
     1322#ifdef DARWIN_GS_HACK
     1323                                 ,gs_was_tcr
     1324#endif
     1325                                 );
     1326}
     1327
     1328#endif
     1329
     1330void
     1331quit_handler(int signum, siginfo_t *info, ExceptionInformation *xp)
    12751332{
    12761333  TCR *tcr = get_tcr(false);
     
    13011358}
    13021359
    1303 void
    1304 altstack_quit_handler(int signum, siginfo_t *info, ExceptionInformation *context)
     1360#ifndef USE_SIGALTSTACK
     1361arbstack_quit_handler(int signum, siginfo_t *info, ExceptionInformation *context)
    13051362{
    13061363#ifdef DARWIN_GS_HACK
    13071364  Boolean gs_was_tcr = ensure_gs_pthread();
    13081365#endif
     1366  TCR *tcr = get_interrupt_tcr(false);
     1367  area *vs = tcr->vs_area;
     1368  BytePtr current_sp = (BytePtr) current_stack_pointer();
     1369
     1370  if ((current_sp >= vs->low) &&
     1371      (current_sp < vs->high)) {
     1372    handle_signal_on_foreign_stack(tcr,
     1373                                   quit_handler,
     1374                                   signum,
     1375                                   info,
     1376                                   context,
     1377                                   (LispObj)__builtin_return_address(0)
     1378#ifdef DARWIN_GS_HACK
     1379                                   ,gs_was_tcr
     1380#endif
     1381                                   );
     1382  } else {
     1383    /* If we're not on the value stack, we pretty much have to be on
     1384       the C stack.  Just run the handler. */
     1385#ifdef DARWIN_GS_HACK
     1386    if (gs_was_tcr) {
     1387      set_gs_address(tcr);
     1388    }
     1389#endif
     1390    quit_handler(signum, info, context);
     1391  }
     1392}
     1393
     1394
     1395#else
     1396void
     1397altstack_quit_handler(int signum, siginfo_t *info, ExceptionInformation *context)
     1398{
     1399#ifdef DARWIN_GS_HACK
     1400  Boolean gs_was_tcr = ensure_gs_pthread();
     1401#endif
    13091402  TCR* tcr = get_tcr(true);
    1310   LispObj *foreign_rsp = find_foreign_rsp(xpGPR(context,Isp), tcr->cs_area, tcr);
    1311 #ifdef LINUX
    1312   fpregset_t fpregs = NULL;
     1403  handle_signal_on_foreign_stack(tcr,
     1404                                 quit_handler,
     1405                                 signum,
     1406                                 info,
     1407                                 context,
     1408                                 (LispObj)__builtin_return_address(0)
     1409#ifdef DARWIN_GS_HACK
     1410                                 ,gs_was_tcr
     1411#endif
     1412                                 );
     1413}
     1414#endif
     1415
     1416#ifdef USE_SIGALTSTACK
     1417#define SUSPEND_RESUME_HANDLER altstack_suspend_resume_handler
     1418#define QUIT_HANDLER altstack_quit_handler
    13131419#else
    1314   void *fpregs = NULL;
    1315 #endif
    1316 #ifdef DARWIN
    1317   MCONTEXT_T mcontextp = NULL;
    1318 #endif
    1319 
    1320   siginfo_t *info_copy = NULL;
    1321   ExceptionInformation *xp = NULL;
    1322 
    1323   if (foreign_rsp) {
    1324 #ifdef LINUX
    1325     foreign_rsp = copy_fpregs(context, foreign_rsp, &fpregs);
    1326 #endif
    1327 #ifdef DARWIN
    1328     foreign_rsp = copy_darwin_mcontext(UC_MCONTEXT(context), foreign_rsp, &mcontextp);
    1329 #endif
    1330     foreign_rsp = copy_siginfo(info, foreign_rsp);
    1331     info_copy = (siginfo_t *)foreign_rsp;
    1332     foreign_rsp = copy_ucontext(context, foreign_rsp, fpregs);
    1333     xp = (ExceptionInformation *)foreign_rsp;
    1334 #ifdef DARWIN
    1335     UC_MCONTEXT(xp) = mcontextp;
    1336 #endif
    1337     *--foreign_rsp = (LispObj)__builtin_return_address(0);
    1338     switch_to_foreign_stack(foreign_rsp,quit_handler,signum,info_copy,xp);
    1339   }
    1340 }
     1420#define SUSPEND_RESUME_HANDLER arbstack_suspend_resume_handler
     1421#define QUIT_HANDLER arbstack_quit_handler
     1422#endif
    13411423
    13421424void
     
    13461428  thread_resume_signal = SIG_RESUME_THREAD;
    13471429
    1348   install_signal_handler(thread_suspend_signal, (void *)altstack_suspend_resume_handler);
    1349   install_signal_handler(thread_resume_signal, (void *)altstack_suspend_resume_handler);
    1350   install_signal_handler(SIGQUIT, (void *)altstack_quit_handler);
     1430  install_signal_handler(thread_suspend_signal, (void *)SUSPEND_RESUME_HANDLER);
     1431  install_signal_handler(thread_resume_signal, (void *)SUSPEND_RESUME_HANDLER);
     1432  install_signal_handler(SIGQUIT, (void *)QUIT_HANDLER);
    13511433}
    13521434
     
    14041486
    14051487
     1488#ifdef USE_SIGALTSTACK
    14061489void
    14071490setup_sigaltstack(area *a)
     
    14131496  stack.ss_flags = 0;
    14141497  mmap(stack.ss_sp,stack.ss_size, PROT_READ|PROT_WRITE|PROT_EXEC,MAP_FIXED|MAP_ANON|MAP_PRIVATE,-1,0);
    1415   sigaltstack(&stack, NULL);
    1416 }
     1498  if (sigaltstack(&stack, NULL) != 0) {
     1499    perror("sigaltstack");
     1500    exit(-1);
     1501  }
     1502}
     1503#endif
    14171504
    14181505extern opcode egc_write_barrier_start, egc_write_barrier_end,
Note: See TracChangeset for help on using the changeset viewer.