1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 syserr_real:
26 procedure (arg_code);
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 dcl arg_code fixed bin;
76 dcl arg_data_code fixed bin;
77 dcl arg_data_len fixed bin;
78 dcl arg_data_pieces_array_ptr ptr;
79 dcl arg_data_ptr ptr;
80 dcl arg_error_code ptr unal;
81 dcl arg_n_data_pieces fixed bin;
82 dcl arg_panic_mess char (*);
83
84
85
86
87 dcl alarm_flag bit (1) aligned;
88 dcl arg_list_ptr ptr;
89 dcl 1 auto_mbuf aligned,
90 2 header like mbuf_header,
91 2 equal char (4) unal;
92 dcl 1 auto_wlog_header aligned like wlog_header;
93 dcl 1 auto_wmess_header aligned like wmess_header;
94 dcl binary_call bit (1);
95 dcl code fixed bin;
96 dcl cont_flag bit (1) aligned;
97 dcl copying_permitted bit (1) aligned;
98 dcl cs_pos fixed bin;
99 dcl data_code fixed bin;
100 dcl data_len fixed bin;
101 dcl data_piece_len fixed bin;
102 dcl data_piece_ptr ptr;
103 dcl data_pieces_array_ptr pointer;
104 dcl data_ptr ptr;
105 dcl error_table_call bit (1);
106 dcl error_table_code fixed bin (35);
107 dcl etmsgp ptr;
108 dcl mbuf_ptr ptr;
109 dcl message_len fixed bin (21);
110 dcl n_data_pieces fixed bin;
111 dcl nargs fixed bin;
112 dcl 1 oc_io aligned like console_io;
113 dcl oc_line_leng fixed bin;
114 dcl oc_printed_leng fixed bin;
115 dcl ocdcm_code fixed bin (35);
116 dcl old_mask bit (72) aligned;
117 dcl old_wlog_ptr ptr;
118 dcl olen fixed bin (19);
119 dcl optr ptr;
120 dcl out_buf char (256) aligned;
121 dcl piece_index fixed bin;
122 dcl print_len fixed bin (21);
123 dcl print_ptr ptr;
124 dcl print_this_line_len fixed bin (21);
125 dcl rtime fixed bin (71);
126 dcl sys_code fixed bin;
127 dcl tenths_min fixed bin;
128 dcl wire_arg bit (72) aligned; note
129 dcl wired bit (1) aligned;
130 dcl wired_wlog_ptr ptr;
131 dcl wired_wmess_ptr ptr;
132 dcl wired_stack_ptr pointer;
133 dcl wmess_len fixed bin;
134 dcl write_flag bit (1) aligned;
135
136
137
138
139 dcl CR_NL char (5) based (addr (CR_NL_bits));
140
141
142
143
144
145
146
147
148
149
150
151
152 dcl binary_data (data_len) bit (36) aligned based (data_ptr);
153 dcl data_piece (data_piece_len) bit (36) aligned based (data_piece_ptr);
154
155 dcl 1 data_pieces_array (n_data_pieces) aligned based (data_pieces_array_ptr),
156
157 2 ptr pointer,
158 2 len fixed bin;
159
160 dcl 1 et aligned based (etmsgp),
161 2 len fixed bin (8) unal,
162 2 msg char (et.len) unal;
163
164
165
166
167 dcl 1 mbuf aligned based (mbuf_ptr),
168 2 header aligned like mbuf_header,
169 2 text char (2047) unal;
170
171 dcl 1 mbuf_header aligned based,
172 2 no_log,
173
174 3 lost char (6) unal,
175 3 seq_num pic "9999" unal,
176 3 comma char (2) unal,
177 3 sys_code pic "9" unal,
178 3 pad char (3) unal,
179 2 time,
180
181 3 hh pic "99" unal,
182 3 mmt pic "99.9" unal,
183 3 pad char (2) unal;
184
185 dcl old_wlog (syserr_data$wired_log_size) bit (36) aligned based (old_wlog_ptr);
186
187
188 dcl wmess_copy (wmess_len) bit (36) aligned based;
189
190
191
192
193 dcl arg_count_ entry (fixed bin);
194 dcl arg_list_ptr_ entry (ptr);
195 dcl formline_ entry (fixed bin, fixed bin, ptr, fixed bin (21), fixed bin, ptr);
196 dcl oc_trans_output_ entry (ptr, fixed bin (21), fixed bin (21), ptr, fixed bin (19), fixed bin, bit (1) aligned);
197 dcl ocdcm_$console_info entry (char (4), bit (36), char (8), fixed bin, fixed bin, fixed bin (35));
198 dcl ocdcm_$drain_io entry ();
199 dcl ocdcm_$priority_io entry (ptr);
200 dcl pmut$bce_and_return entry options (variable);
201 dcl pmut$read_mask entry (bit (72) aligned);
202 dcl pmut$set_mask entry (bit (72) aligned);
203 dcl pmut$unwire_unmask entry (bit (72) aligned, pointer);
204 dcl pmut$wire_and_mask entry (bit (72) aligned, pointer);
205 dcl pxss$unique_ring_0_wakeup entry (bit (36) aligned, fixed bin (71), fixed bin (71), fixed bin (35));
206 dcl syserr entry options (variable);
207 dcl syserr_copy$lock entry ();
208 dcl syserr_copy$unlock entry ();
209 dcl syserr_copy$wired_log entry (ptr);
210 dcl syserr_real$syserr_real entry options (variable);
211 dcl terminate_proc entry (fixed bin (35));
212 dcl wired_utility_$grow_stack_frame entry (fixed bin) returns (ptr);
213
214
215
216
217 dcl error_table_$ ext;
218 dcl pds$process_group_id char (32) aligned ext;
219 dcl pds$processid bit (36) aligned ext;
220 dcl pds$apt_ptr pointer ext;
221 dcl prds$ ext;
222 dcl prds$idle_ptr pointer ext;
223 dcl scs$open_level bit (72) aligned ext;
224 dcl sys_info$time_correction_constant fixed bin (71) ext;
225 dcl syserr_data$logger_ec fixed bin (71) ext;
226 dcl syserr_data$logger_proc_id bit (36) aligned ext;
227 dcl syserr_data$wired_log_size fixed bin ext;
228
229
230
231
232 dcl cleanup condition;
233
234 dcl (add, addcharno, addr, addrel, baseno, bin, bit, byte, clock, currentsize, divide, length, max, min, mod, multiply, ptr, rel, rtrim, segno, size, stac, stackbaseptr, stacq, string, substr, unspec, wordno) builtin;
235
236
237
238
239 dcl CR_NL_bits bit (45) static options (constant) init ("015012177177177"b3);
240
241 dcl bad_ring1_msg char (24) static options (constant) init ("syserr: Bad ring 1 call.");
242 dcl crash_msg char (46) static options (constant) init ("Multics not in operation; control process: ^a.");
243 dcl lock_msg char (21) static options (constant) init ("syserr: Mylock error.");
244 dcl terminate_msg char (33) static options (constant) init ("Now terminating user process: ^a.");
245 %page;
246
247
248
249 cs_pos = 2;
250 call ring0_setup;
251
252 syserr_start:
253 data_len = 0;
254
255 call arg_list_ptr_ (arg_list_ptr);
256 call SETUP_AND_TEXT;
257 go to COMMON;
258
259
260
261
262 binary:
263 entry (arg_code, arg_data_ptr, arg_data_code, arg_data_len);
264
265 cs_pos = 5;
266 call ring0_setup;
267
268 syserr_binary_start:
269 data_len = arg_data_len;
270
271 call arg_list_ptr_ (arg_list_ptr);
272 call SETUP_AND_TEXT;
273 if data_len > 0 then do;
274 binary_call = "1"b;
275 data_code = arg_data_code;
276 data_ptr -> binary_data = arg_data_ptr -> binary_data;
277 end;
278
279 go to COMMON;
280
281
282
283
284 multiple_binary:
285 entry (arg_code, arg_data_pieces_array_ptr, arg_n_data_pieces, arg_data_code);
286
287 cs_pos = 5;
288 call ring0_setup;
289
290 syserr_multiple_binary_start:
291 data_pieces_array_ptr = arg_data_pieces_array_ptr;
292 n_data_pieces = arg_n_data_pieces;
293 data_len = 0;
294 do piece_index = 1 to n_data_pieces;
295 data_len = data_len + data_pieces_array (piece_index).len;
296 end;
297
298 call arg_list_ptr_ (arg_list_ptr);
299 call SETUP_AND_TEXT;
300
301 if data_len > 0 then do;
302 binary_call = "1"b;
303 data_code = arg_data_code;
304 data_piece_ptr = data_ptr;
305 do piece_index = 1 to n_data_pieces;
306 data_piece_len = data_pieces_array (piece_index).len;
307 data_piece_ptr -> data_piece = data_pieces_array (piece_index).ptr -> data_piece;
308 data_piece_ptr = addrel (data_piece_ptr, data_piece_len);
309 end;
310 end;
311 goto COMMON;
312
313
314
315
316 error_code:
317 entry (arg_code, arg_error_code);
318
319 cs_pos = 3;
320 call ring0_setup;
321
322 syserr_error_start:
323 error_table_call = "1"b;
324 data_len = 0;
325
326 call arg_list_ptr_ (arg_list_ptr);
327 call SETUP_AND_TEXT;
328 go to COMMON;
329 %page;
330
331
332
333
334 ring1:
335 entry (arg_code);
336
337 cs_pos = 2;
338 call arg_count_ (nargs);
339 call ring1_setup;
340 go to syserr_start;
341
342
343 ring1_error_code:
344 entry (arg_code, arg_error_code);
345
346 cs_pos = 3;
347 call arg_count_ (nargs);
348 call ring1_setup;
349 go to syserr_error_start;
350
351
352 ring1_binary:
353 entry (arg_code, arg_data_ptr, arg_data_code, arg_data_len);
354
355 cs_pos = 5;
356 call arg_count_ (nargs);
357 call ring1_setup;
358 go to syserr_binary_start;
359
360
361 ring1_multiple_binary:
362 entry (arg_code, arg_data_pieces_array_ptr, arg_n_data_pieces, arg_data_code);
363 cs_pos = 5;
364 call arg_count_ (nargs);
365 call ring1_setup;
366 goto syserr_multiple_binary_start;
367 %page;
368 COMMON:
369 wired = "0"b;
370 on cleanup
371 begin;
372 if wired then call pmut$unwire_unmask (wire_arg, wired_stack_ptr);
373 end;
374 copying_permitted = "0"b;
375
376 sd_ptr = addr (syserr_data$syserr_area);
377
378 call pmut$read_mask (old_mask);
379 if old_mask = scs$open_level then
380 if pds$apt_ptr ^= prds$idle_ptr then
381 if stackbaseptr () ^= addr (prds$) then
382 if ^termp_flags (sys_code)
383 & ^crash_flags (sys_code) then
384 if sd.log_flag then
385
386 if addr (syserr_log_data$) -> syserr_log_data.lock.pid ^= pds$processid then
387
388 copying_permitted = "1"b;
389
390 write_flag = write_flags (sys_code);
391 alarm_flag = alarm_flags (sys_code);
392
393 rtime = clock ();
394
395 auto_wmess_header.code = code;
396 auto_wmess_header.time = rtime;
397 auto_wmess_header.pad = "0"b;
398 auto_wmess_header.process_id = pds$processid;
399 auto_wmess_header.data_code = data_code;
400
401 wired_wlog_ptr = addr (syserr_data$wired_log_area);
402
403 if copying_permitted then do;
404
405
406
407 call syserr_copy$lock ();
408 old_wlog_ptr = wired_utility_$grow_stack_frame (syserr_data$wired_log_size);
409 end;
410
411 call pmut$wire_and_mask (wire_arg, wired_stack_ptr);
412 wired = "1"b;
413
414
415 Note
416
417 if ^sd.ocdcm_init_flag then call panic (mbuf.text);
418
419 call SR_LOCK ();
420
421
422
423
424 print_ptr = addr (mbuf.time);
425 print_len = message_len + length (string (mbuf.time));
426
427 tenths_min = mod (divide (rtime - sys_info$time_correction_constant, 6000000, 52, 0), 14400);
428
429 auto_mbuf.header.time.hh = divide (tenths_min, 600, 5);
430 auto_mbuf.header.time.mmt = tenths_min - divide (tenths_min, 600, 5) * 600;
431 auto_mbuf.header.time.pad = "";
432 %page;
433 if ^sd.log_flag then
434
435 auto_wmess_header.seq_num = 0;
436 else if copying_permitted then do;
437
438
439
440 if wired_wlog_ptr -> wlog.count > 0 then do;
441 old_wlog_ptr -> old_wlog = wired_wlog_ptr -> old_wlog;
442 wired_wlog_ptr -> wlog.next = rel (addr (wired_wlog_ptr -> wlog.buffer));
443 wired_wlog_ptr -> wlog.count = 0;
444 end;
445 else old_wlog_ptr -> wlog.count = 0;
446
447 auto_wmess_header.seq_num, wired_wlog_ptr -> wlog.seq_num = wired_wlog_ptr -> wlog.seq_num + 1;
448 end;
449 %page;
450
451
452
453
454
455 else do;
456
457
458
459
460
461 wired_wmess_ptr = ptr (wired_wlog_ptr, wired_wlog_ptr -> wlog.next);
462
463 RETRY_ADD:
464
465
466
467
468
469
470
471 if wmess_len > (size (wlog_header) + wired_wlog_ptr -> wlog.bsize)
472 - (bin (wired_wlog_ptr -> wlog.next, 18) - wordno (wired_wlog_ptr)) then do;
473
474 if binary_call then do;
475 binary_call = "0"b;
476 wmess_len = wmess_len - auto_wmess_header.data_size;
477 auto_wmess_header.data_size = 0;
478 go to RETRY_ADD;
479 end;
480
481 auto_wmess_header.seq_num,
482 wired_wlog_ptr -> wlog.seq_num = wired_wlog_ptr -> wlog.seq_num + 1;
483
484 if wifnl_flags (sys_code) then do;
485 write_flag = "1"b;
486 print_ptr = addr (mbuf.no_log); note
487 print_len = print_len + length (string (mbuf.no_log));
488 auto_mbuf.header.no_log.lost = "*lost";
489 auto_mbuf.header.no_log.comma = ",";
490 auto_mbuf.header.no_log.pad = "";
491 auto_mbuf.header.no_log.seq_num = mod (auto_wmess_header.seq_num, 10000);
492
493 auto_mbuf.header.no_log.sys_code = sys_code;
494 end;
495 end;
496 else do;
497
498
499
500 auto_wmess_header.seq_num,
501 wired_wlog_ptr -> wlog.seq_num = wired_wlog_ptr -> wlog.seq_num + 1;
502
503 wired_wlog_ptr -> wlog.next = bit (add (bin (wired_wlog_ptr -> wlog.next, 18), wmess_len, 18), 18);
504 wired_wlog_ptr -> wlog.count = wired_wlog_ptr -> wlog.count + 1;
505
506 wmess_ptr -> wmess.header = auto_wmess_header;
507 wired_wmess_ptr -> wmess_copy = wmess_ptr -> wmess_copy;
508 end;
509
510 call WAKEUP_DAEMON;
511 end;
512 %page;
513
514 Note
515
516
517
518 Note
519
520 if write_flag then do;
521
522
523
524
525 if ^alarm_flag & mbuf.text = sd.prev_text_written then do;
526
527 print_len = print_len - message_len + 1;
528 message_len = 1;
529 print_ptr = addrel (addr (auto_mbuf), wordno (print_ptr) - wordno (mbuf_ptr));
530 if mbuf.text ^= " " then auto_mbuf.equal = "=";
531 else auto_mbuf.equal = "";
532
533 end;
534 else do;
535 if message_len > length (sd.prev_text_written) then
536 unspec (sd.prev_text_written) = "0"b;
537
538 else sd.prev_text_written = substr (mbuf.text, 1, message_len);
539
540 mbuf_ptr -> mbuf_header = auto_mbuf.header;
541 end;
542 end;
543 %page;
544
545
546 call SR_UNLOCK;
547
548 if write_flag then do;
549 optr = addr (out_buf);
550 cont_flag = "0"b;
551
552
553
554
555
556
557
558 call ocdcm_$console_info ("", "0"b, "", 0, oc_line_leng, ocdcm_code);
559
560 if ocdcm_code ^= 0 then oc_line_leng = 80;
561
562 do while (print_len > 0);
563 call oc_trans_output_ (print_ptr, print_len, print_this_line_len, optr, olen, oc_line_leng, cont_flag);
564 oc_printed_leng = multiply (olen, 4, 17);
565
566 oc_io.read = "0"b;
567 oc_io.alert = alarm_flag;
568 oc_io.sequence_no = auto_wmess_header.seq_num;
569 oc_io.event_chan = 0;
570
571 if print_this_line_len >= print_len then do;
572 oc_printed_leng = length (rtrim (substr (out_buf, 1, oc_printed_leng), byte (127)));
573 substr (out_buf, oc_printed_leng + 1, 5) = CR_NL;
574 olen = divide (oc_printed_leng + 5, 4, 17);
575 oc_printed_leng = multiply (olen, 4, 17);
576 end;
577
578
579 print_ptr = addcharno (print_ptr, print_this_line_len);
580 print_len = print_len - print_this_line_len;
581 alarm_flag = "0"b;
582
583 oc_io.leng = olen;
584 oc_io.text = substr (out_buf, 1, oc_printed_leng);
585
586 call ocdcm_$priority_io (addr (oc_io));
587 end;
588 %page;
589
590
591
592 if termp_flags (sys_code) then do;
593 call syserr_real$syserr_real (LOG, terminate_msg, pds$process_group_id);
594 call pmut$set_mask (scs$open_level);
595 call terminate_proc (error_table_code);
596 end;
597
598
599 else if crash_flags (sys_code) then do;
600
601
602
603
604
605 call syserr_real$syserr_real (ANNOUNCE, crash_msg, pds$process_group_id);
606
607 call ocdcm_$drain_io ();
608
609 call pmut$bce_and_return;
610 end;
611 end;
612 %page;
613
614
615
616 call pmut$unwire_unmask (wire_arg, wired_stack_ptr);
617
618 if copying_permitted then do;
619 if old_wlog_ptr -> wlog.count > 0 then call syserr_copy$wired_log (old_wlog_ptr);
620 wlog_ptr -> wlog_header = auto_wlog_header;
621 wlog.count = 1;
622 wmess_ptr -> wmess_header = auto_wmess_header;
623 call syserr_copy$wired_log (wlog_ptr);
624 call syserr_copy$unlock;
625 end;
626 return;
627 %page;
628
629
630 syserr_reset:
631 entry;
632
633 addr (syserr_data$syserr_area) -> sd.lock = "0"b;
634
635 return;
636
637
638
639
640
641
642 panic:
643 entry (arg_panic_mess);
644
645 fgbxp = addr (flagbox$);
646 fgbx.message = arg_panic_mess;
647 fgbx.alert, fgbx.mess = "1"b;
648
649 do while ("1"b);
650 call pmut$bce_and_return;
651 end;
652 %page;
653
654
655
656 ring1_setup:
657 proc;
658
659 binary_call = "0"b;
660 data_code = 0;
661 error_table_call = "0"b;
662
663 if nargs < cs_pos then do;
664 call syserr (4, bad_ring1_msg);
665 go to ring1_return;
666 end;
667 code = arg_code;
668 sys_code = mod (code, 10);
669 code = divide (code, 10, 17, 0);
670 if code < 0 | code > 24 then code = 24;
671 code = 10 * code + sys_code;
672
673 end ring1_setup;
674
675
676 ring1_return:
677 return;
678
679
680 ring0_setup: proc;
681
682 binary_call = "0"b;
683 data_code = 0;
684 error_table_call = "0"b;
685
686 code = arg_code;
687 sys_code = mod (code, 10);
688 return;
689 end ring0_setup;
690 %page;
691
692
693
694 SR_UNLOCK:
695 procedure;
696
697 if stacq (sd.lock, "0"b, sd.lock) then ;
698
699 end SR_UNLOCK;
700
701 SR_LOCK:
702 procedure;
703
704 if sd.lock = pds$processid then call panic (lock_msg);
705 do while (^stac (addr (sd.lock), pds$processid));
706 end;
707 return;
708 end SR_LOCK;
709
710 WAKEUP_DAEMON:
711 procedure;
712
713 call pxss$unique_ring_0_wakeup (syserr_data$logger_proc_id, syserr_data$logger_ec, 0, (0));
714 return;
715 end WAKEUP_DAEMON;
716 %page;
717 SETUP_AND_TEXT:
718 proc;
719
720
721
722
723 dcl len_for_et fixed bin;
724 dcl max_header_size fixed bin;
725 dcl text_and_data_size fixed bin;
726 dcl work_ptr ptr;
727
728 auto_wmess_header.text_len, message_len = 2047;
729 auto_wmess_header.data_size = data_len;
730
731 text_and_data_size = currentsize (addr (auto_wmess_header) -> wmess);
732
733 max_header_size = max (size (wlog_header) + size (wmess_header), size (mbuf_header));
734
735 work_ptr = wired_utility_$grow_stack_frame (max_header_size + text_and_data_size);
736
737 wlog_ptr = addrel (work_ptr, max_header_size - (size (wlog_header) + size (wmess_header)));
738 wmess_ptr = addrel (wlog_ptr, size (wlog_header));
739 mbuf_ptr = addrel (work_ptr, max_header_size - size (mbuf_header));
740
741 call formline_ (cs_pos, cs_pos + 1, addr (wmess.text), message_len, 1, arg_list_ptr);
742
743
744 if message_len = 0 then do;
745 substr (wmess.text, 1, 4) = "";
746 message_len = 1;
747 end;
748
749 error_table_code = -9;
750 if error_table_call then do;
751 etmsgp = arg_error_code;
752 unspec (error_table_code) = unspec (arg_error_code);
753 if baseno (etmsgp) = "077777"b3 then
754 etmsgp = ptr (addr (error_table_$), rel (etmsgp));
755
756 if segno (etmsgp) = 0 then error_table_code = -9;
757 else do;
758 len_for_et = auto_wmess_header.text_len - message_len;
759
760 len_for_et = min (len_for_et, et.len + 1);
761 if len_for_et > 0 then do;
762 substr (wmess.text, message_len + 1, 1) = " ";
763 substr (wmess.text, message_len + 2, len_for_et - 1) = et.msg;
764
765 message_len = message_len + len_for_et;
766
767 end;
768 end;
769 end;
770
771 auto_wmess_header.text_len = message_len;
772 wmess_len = currentsize (addr (auto_wmess_header) -> wmess);
773 data_ptr = addrel (wmess_ptr, wmess_len - data_len);
774 return;
775 end SETUP_AND_TEXT;
776 %page; %include flagbox;
777 %page; %include oc_data;
778 %page; %include syserr_actions;
779 %page; %include syserr_constants;
780 %page; %include syserr_data;
781 %page; %include syserr_log_dcls;
782 %page;
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839 end syserr_real;