all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#75482: scratch/igc: Building with ASan fails
@ 2025-01-10 22:04 Stefan Kangas
  2025-01-11  4:22 ` Gerd Möllmann
  2025-01-11  5:20 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 9+ messages in thread
From: Stefan Kangas @ 2025-01-10 22:04 UTC (permalink / raw)
  To: 75482; +Cc: gerd, pipcet

I was experimenting with building the scratch/igc branch with
-fsanitize=address, and I ran into this:

=================================================================
==134==ERROR: AddressSanitizer: stack-buffer-underflow on address
0x00016ac1df20 at pc 0x00010617584c bp 0x00016ac1d690 sp
0x00016ac1d688
READ of size 8 at 0x00016ac1df20 thread T0
    #0 0x106175848 in scan_ambig igc.c:1552
    #1 0x106529218 in StackScan ss.c:68
    #2 0x10650e8a4 in ThreadScan thxc.c:242
    #3 0x10650e46c in RootScan root.c
    #4 0x10654ad88 in traceScanRootRes trace.c:528
    #5 0x10650cec8 in TraceStart trace.c:1694
    #6 0x106500fd8 in PolicyStartTrace policy.c:335
    #7 0x106500544 in TracePoll trace.c:1840
    #8 0x1064ec440 in ArenaPoll global.c:745
    #9 0x1064ed30c in mps_ap_fill mpsi.c:1097
    #10 0x10617d660 in alloc_impl igc.c:3954
    #11 0x1061620c8 in alloc igc.c:3982
    #12 0x106161f28 in igc_make_cons igc.c:4011
    #13 0x105af5dc4 in Fcons alloc.c:2958
    #14 0x105c6cbc4 in eval_sub eval.c:2692
    #15 0x105c6e8fc in Fprogn eval.c:452
    #16 0x105cab3dc in funcall_lambda eval.c:3365
    #17 0x105ca0924 in apply_lambda eval.c:3230
    #18 0x105c6bfb4 in eval_sub eval.c:2660
    #19 0x105c6aa54 in eval_sub eval.c:2601
    #20 0x105c6e8fc in Fprogn eval.c:452
    #21 0x105cab3dc in funcall_lambda eval.c:3365
    #22 0x105ca683c in funcall_general eval.c:3059
    #23 0x105c75be0 in Ffuncall eval.c:3108
    #24 0x105ca1180 in Fapply eval.c:2737
    #25 0x105c664b8 in apply1 eval.c:2996
    #26 0x105c6ced0 in eval_sub eval.c:2697
    #27 0x105c6e8fc in Fprogn eval.c:452
    #28 0x105cab3dc in funcall_lambda eval.c:3365
    #29 0x105ca683c in funcall_general eval.c:3059
    #30 0x105c75be0 in Ffuncall eval.c:3108
    #31 0x105ca1180 in Fapply eval.c:2737
    #32 0x105c664b8 in apply1 eval.c:2996
    #33 0x105c6ced0 in eval_sub eval.c:2697
    #34 0x105c6aa54 in eval_sub eval.c:2601
    #35 0x105c6ffd8 in Fsetq eval.c:499
    #36 0x105c69f28 in eval_sub eval.c:2564
    #37 0x105c6d050 in eval_sub eval.c:2699
    #38 0x105c6e8fc in Fprogn eval.c:452
    #39 0x105c6f41c in prog_ignore eval.c:463
    #40 0x105c849e4 in Fwhile eval.c:1143
    #41 0x105c69f28 in eval_sub eval.c:2564
    #42 0x105c6e8fc in Fprogn eval.c:452
    #43 0x105c6e458 in Fif eval.c:408
    #44 0x105c69f28 in eval_sub eval.c:2564
    #45 0x105c6d050 in eval_sub eval.c:2699
    #46 0x105c6e8fc in Fprogn eval.c:452
    #47 0x105c6f41c in prog_ignore eval.c:463
    #48 0x105c849e4 in Fwhile eval.c:1143
    #49 0x105c69f28 in eval_sub eval.c:2564
    #50 0x105c6e8fc in Fprogn eval.c:452
    #51 0x105c80f4c in FletX eval.c:1055
    #52 0x105c69f28 in eval_sub eval.c:2564
    #53 0x105c6d050 in eval_sub eval.c:2699
    #54 0x105c6e8fc in Fprogn eval.c:452
    #55 0x105cab3dc in funcall_lambda eval.c:3365
    #56 0x105ca0924 in apply_lambda eval.c:3230
    #57 0x105c6bfb4 in eval_sub eval.c:2660
    #58 0x105c6e318 in Fif eval.c:407
    #59 0x105c69f28 in eval_sub eval.c:2564
    #60 0x105c6e8fc in Fprogn eval.c:452
    #61 0x105c83be8 in Flet eval.c:1122
    #62 0x105c69f28 in eval_sub eval.c:2564
    #63 0x105c6e8fc in Fprogn eval.c:452
    #64 0x105cab3dc in funcall_lambda eval.c:3365
    #65 0x105ca683c in funcall_general eval.c:3059
    #66 0x105c75be0 in Ffuncall eval.c:3108
    #67 0x105c6a520 in eval_sub eval.c:2585
    #68 0x105c6e8fc in Fprogn eval.c:452
    #69 0x105c6f080 in Fcond eval.c:432
    #70 0x105c69f28 in eval_sub eval.c:2564
    #71 0x105c6e8fc in Fprogn eval.c:452
    #72 0x105c80f4c in FletX eval.c:1055
    #73 0x105c69f28 in eval_sub eval.c:2564
    #74 0x105c6e8fc in Fprogn eval.c:452
    #75 0x105c6f080 in Fcond eval.c:432
    #76 0x105c69f28 in eval_sub eval.c:2564
    #77 0x105c6e8fc in Fprogn eval.c:452
    #78 0x105c80f4c in FletX eval.c:1055
    #79 0x105c69f28 in eval_sub eval.c:2564
    #80 0x105c6d050 in eval_sub eval.c:2699
    #81 0x105c6e8fc in Fprogn eval.c:452
    #82 0x105c83be8 in Flet eval.c:1122
    #83 0x105c69f28 in eval_sub eval.c:2564
    #84 0x105c6e8fc in Fprogn eval.c:452
    #85 0x105c6e458 in Fif eval.c:408
    #86 0x105c69f28 in eval_sub eval.c:2564
    #87 0x105c6e8fc in Fprogn eval.c:452
    #88 0x105c83be8 in Flet eval.c:1122
    #89 0x105c69f28 in eval_sub eval.c:2564
    #90 0x105c6d050 in eval_sub eval.c:2699
    #91 0x105c6e8fc in Fprogn eval.c:452
    #92 0x105cab3dc in funcall_lambda eval.c:3365
    #93 0x105ca0924 in apply_lambda eval.c:3230
    #94 0x105c6bfb4 in eval_sub eval.c:2660
    #95 0x105c6e318 in Fif eval.c:407
    #96 0x105c69f28 in eval_sub eval.c:2564
    #97 0x105c6e8fc in Fprogn eval.c:452
    #98 0x105c69f28 in eval_sub eval.c:2564
    #99 0x105c6ffd8 in Fsetq eval.c:499
    #100 0x105c69f28 in eval_sub eval.c:2564
    #101 0x105c6e8fc in Fprogn eval.c:452
    #102 0x105c6f41c in prog_ignore eval.c:463
    #103 0x105c849e4 in Fwhile eval.c:1143
    #104 0x105c69f28 in eval_sub eval.c:2564
    #105 0x105c6e8fc in Fprogn eval.c:452
    #106 0x105c80f4c in FletX eval.c:1055
    #107 0x105c69f28 in eval_sub eval.c:2564
    #108 0x105c6d050 in eval_sub eval.c:2699
    #109 0x105c6e8fc in Fprogn eval.c:452
    #110 0x105cab3dc in funcall_lambda eval.c:3365
    #111 0x105ca0924 in apply_lambda eval.c:3230
    #112 0x105c6bfb4 in eval_sub eval.c:2660
    #113 0x105c6e318 in Fif eval.c:407
    #114 0x105c69f28 in eval_sub eval.c:2564
    #115 0x105c6e8fc in Fprogn eval.c:452
    #116 0x105c83be8 in Flet eval.c:1122
    #117 0x105c69f28 in eval_sub eval.c:2564
    #118 0x105c6e8fc in Fprogn eval.c:452
    #119 0x105cab3dc in funcall_lambda eval.c:3365
    #120 0x105ca683c in funcall_general eval.c:3059
    #121 0x105c75be0 in Ffuncall eval.c:3108
    #122 0x105c6a520 in eval_sub eval.c:2585
    #123 0x105c6e8fc in Fprogn eval.c:452
    #124 0x105c6f080 in Fcond eval.c:432
    #125 0x105c69f28 in eval_sub eval.c:2564
    #126 0x105c6e8fc in Fprogn eval.c:452
    #127 0x105c80f4c in FletX eval.c:1055
    #128 0x105c69f28 in eval_sub eval.c:2564
    #129 0x105c6e8fc in Fprogn eval.c:452
    #130 0x105c6f080 in Fcond eval.c:432
    #131 0x105c69f28 in eval_sub eval.c:2564
    #132 0x105c6e8fc in Fprogn eval.c:452
    #133 0x105c80f4c in FletX eval.c:1055
    #134 0x105c69f28 in eval_sub eval.c:2564
    #135 0x105c6d050 in eval_sub eval.c:2699
    #136 0x105c6e8fc in Fprogn eval.c:452
    #137 0x105c83be8 in Flet eval.c:1122
    #138 0x105c69f28 in eval_sub eval.c:2564
    #139 0x105c6e8fc in Fprogn eval.c:452
    #140 0x105c6e458 in Fif eval.c:408
    #141 0x105c69f28 in eval_sub eval.c:2564
    #142 0x105c6e8fc in Fprogn eval.c:452
    #143 0x105c83be8 in Flet eval.c:1122
    #144 0x105c69f28 in eval_sub eval.c:2564
    #145 0x105c6d050 in eval_sub eval.c:2699
    #146 0x105c6e8fc in Fprogn eval.c:452
    #147 0x105cab3dc in funcall_lambda eval.c:3365
    #148 0x105ca0924 in apply_lambda eval.c:3230
    #149 0x105c6bfb4 in eval_sub eval.c:2660
    #150 0x105c6e318 in Fif eval.c:407
    #151 0x105c69f28 in eval_sub eval.c:2564
    #152 0x105c6e8fc in Fprogn eval.c:452
    #153 0x105c69f28 in eval_sub eval.c:2564
    #154 0x105c6ffd8 in Fsetq eval.c:499
    #155 0x105c69f28 in eval_sub eval.c:2564
    #156 0x105c6e8fc in Fprogn eval.c:452
    #157 0x105c6f41c in prog_ignore eval.c:463
    #158 0x105c849e4 in Fwhile eval.c:1143
    #159 0x105c69f28 in eval_sub eval.c:2564
    #160 0x105c6e8fc in Fprogn eval.c:452
    #161 0x105c80f4c in FletX eval.c:1055
    #162 0x105c69f28 in eval_sub eval.c:2564
    #163 0x105c6d050 in eval_sub eval.c:2699
    #164 0x105c6e8fc in Fprogn eval.c:452
    #165 0x105cab3dc in funcall_lambda eval.c:3365
    #166 0x105ca0924 in apply_lambda eval.c:3230
    #167 0x105c6bfb4 in eval_sub eval.c:2660
    #168 0x105c6e318 in Fif eval.c:407
    #169 0x105c69f28 in eval_sub eval.c:2564
    #170 0x105c6e8fc in Fprogn eval.c:452
    #171 0x105c83be8 in Flet eval.c:1122
    #172 0x105c69f28 in eval_sub eval.c:2564
    #173 0x105c6e8fc in Fprogn eval.c:452
    #174 0x105cab3dc in funcall_lambda eval.c:3365
    #175 0x105ca683c in funcall_general eval.c:3059
    #176 0x105c75be0 in Ffuncall eval.c:3108
    #177 0x105c6a520 in eval_sub eval.c:2585
    #178 0x105c6e8fc in Fprogn eval.c:452
    #179 0x105c6f080 in Fcond eval.c:432
    #180 0x105c69f28 in eval_sub eval.c:2564
    #181 0x105c6e8fc in Fprogn eval.c:452
    #182 0x105c80f4c in FletX eval.c:1055
    #183 0x105c69f28 in eval_sub eval.c:2564
    #184 0x105c6e8fc in Fprogn eval.c:452
    #185 0x105c6f080 in Fcond eval.c:432
    #186 0x105c69f28 in eval_sub eval.c:2564
    #187 0x105c6e8fc in Fprogn eval.c:452
    #188 0x105c80f4c in FletX eval.c:1055
    #189 0x105c69f28 in eval_sub eval.c:2564
    #190 0x105c6d050 in eval_sub eval.c:2699
    #191 0x105c6e8fc in Fprogn eval.c:452
    #192 0x105c83be8 in Flet eval.c:1122
    #193 0x105c69f28 in eval_sub eval.c:2564
    #194 0x105c6e8fc in Fprogn eval.c:452
    #195 0x105c6e458 in Fif eval.c:408
    #196 0x105c69f28 in eval_sub eval.c:2564
    #197 0x105c6e8fc in Fprogn eval.c:452
    #198 0x105c83be8 in Flet eval.c:1122
    #199 0x105c69f28 in eval_sub eval.c:2564
    #200 0x105c6d050 in eval_sub eval.c:2699
    #201 0x105c6e8fc in Fprogn eval.c:452
    #202 0x105cab3dc in funcall_lambda eval.c:3365
    #203 0x105ca0924 in apply_lambda eval.c:3230
    #204 0x105c6bfb4 in eval_sub eval.c:2660
    #205 0x105c6e318 in Fif eval.c:407
    #206 0x105c69f28 in eval_sub eval.c:2564
    #207 0x105c6e8fc in Fprogn eval.c:452
    #208 0x105c69f28 in eval_sub eval.c:2564
    #209 0x105c6ffd8 in Fsetq eval.c:499
    #210 0x105c69f28 in eval_sub eval.c:2564
    #211 0x105c6e8fc in Fprogn eval.c:452
    #212 0x105c6f41c in prog_ignore eval.c:463
    #213 0x105c849e4 in Fwhile eval.c:1143
    #214 0x105c69f28 in eval_sub eval.c:2564
    #215 0x105c6e8fc in Fprogn eval.c:452
    #216 0x105c80f4c in FletX eval.c:1055
    #217 0x105c69f28 in eval_sub eval.c:2564
    #218 0x105c6d050 in eval_sub eval.c:2699
    #219 0x105c6e8fc in Fprogn eval.c:452
    #220 0x105cab3dc in funcall_lambda eval.c:3365
    #221 0x105ca0924 in apply_lambda eval.c:3230
    #222 0x105c6bfb4 in eval_sub eval.c:2660
    #223 0x105c6e318 in Fif eval.c:407
    #224 0x105c69f28 in eval_sub eval.c:2564
    #225 0x105c6e8fc in Fprogn eval.c:452
    #226 0x105c69f28 in eval_sub eval.c:2564
    #227 0x105c6ffd8 in Fsetq eval.c:499
    #228 0x105c69f28 in eval_sub eval.c:2564
    #229 0x105c6e8fc in Fprogn eval.c:452
    #230 0x105c6f41c in prog_ignore eval.c:463
    #231 0x105c849e4 in Fwhile eval.c:1143
    #232 0x105c69f28 in eval_sub eval.c:2564
    #233 0x105c6e8fc in Fprogn eval.c:452
    #234 0x105c80f4c in FletX eval.c:1055
    #235 0x105c69f28 in eval_sub eval.c:2564
    #236 0x105c6d050 in eval_sub eval.c:2699
    #237 0x105c6e8fc in Fprogn eval.c:452
    #238 0x105cab3dc in funcall_lambda eval.c:3365
    #239 0x105ca0924 in apply_lambda eval.c:3230
    #240 0x105c6bfb4 in eval_sub eval.c:2660
    #241 0x105ca07f0 in apply_lambda eval.c:3225
    #242 0x105c6bfb4 in eval_sub eval.c:2660
    #243 0x105ca07f0 in apply_lambda eval.c:3225
    #244 0x105c6bfb4 in eval_sub eval.c:2660
    #245 0x105c6e8fc in Fprogn eval.c:452
    #246 0x105c83be8 in Flet eval.c:1122
    #247 0x105c69f28 in eval_sub eval.c:2564
    #248 0x105c6e8fc in Fprogn eval.c:452
    #249 0x105c83be8 in Flet eval.c:1122
    #250 0x105c69f28 in eval_sub eval.c:2564
    #251 0x105c6e8fc in Fprogn eval.c:452
    #252 0x105c80f4c in FletX eval.c:1055
    #253 0x105c69f28 in eval_sub eval.c:2564
    #254 0x105c6e8fc in Fprogn eval.c:452

Address 0x00016ac1df20 is located in stack of thread T0 at offset 0 in frame
    #0 0x10617d258 in alloc_impl igc.c:3945

  This frame has 1 object(s):
    [32, 40) 'p' (line 3946)
HINT: this may be a false positive if your program uses some custom
stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-underflow igc.c:1552 in scan_ambig
Shadow bytes around the buggy address:
  0x00016ac1dc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00016ac1dd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00016ac1dd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00016ac1de00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00016ac1de80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x00016ac1df00: 00 00 00 00[f1]f1 f1 f1 00 f3 f3 f3 00 00 00 00
  0x00016ac1df80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00016ac1e000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00016ac1e080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00016ac1e100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00016ac1e180: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 f2 f2 f2
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==134==ABORTING
Fatal error 6: Aborted
gmake[2]: *** [Makefile:1022: bootstrap-emacs.pdmp] Abort trap: 6

I'm not sure if ASan is supposed to be supported on this branch?

In any case, I had the idea to do the following,

diff --git a/src/igc.c b/src/igc.c
index 15db61e709d..9bc0eac970c 100644
--- a/src/igc.c
+++ b/src/igc.c
@@ -1542,7 +1542,7 @@ scan_specpdl (mps_ss_t ss, void *start, void
*end, void *closure)
    references may be either tagged words or pointers.  This is used for
    blocks allocated with malloc and thread stacks.  */

-static mps_res_t
+static mps_res_t ATTRIBUTE_NO_SANITIZE_ADDRESS
 scan_ambig (mps_ss_t ss, void *start, void *end, void *closure)
 {
   MPS_SCAN_BEGIN (ss)

but it seems like the ASan build still loses, currently with this
repeated error while compiling emacs-lisp/radix-tree.elc:

Re-entering top level after C stack overflow





^ permalink raw reply related	[flat|nested] 9+ messages in thread

* bug#75482: scratch/igc: Building with ASan fails
  2025-01-10 22:04 bug#75482: scratch/igc: Building with ASan fails Stefan Kangas
@ 2025-01-11  4:22 ` Gerd Möllmann
  2025-01-11  5:41   ` Gerd Möllmann
  2025-01-11  5:20 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 9+ messages in thread
From: Gerd Möllmann @ 2025-01-11  4:22 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 75482, gerd, pipcet

Stefan Kangas <stefankangas@gmail.com> writes:

> I was experimenting with building the scratch/igc branch with
> -fsanitize=address, and I ran into this:
>
> =================================================================
> ==134==ERROR: AddressSanitizer: stack-buffer-underflow on address
> 0x00016ac1df20 at pc 0x00010617584c bp 0x00016ac1d690 sp
> 0x00016ac1d688
> READ of size 8 at 0x00016ac1df20 thread T0
>     #0 0x106175848 in scan_ambig igc.c:1552
>     #1 0x106529218 in StackScan ss.c:68
>     #2 0x10650e8a4 in ThreadScan thxc.c:242
>     #3 0x10650e46c in RootScan root.c
>     #4 0x10654ad88 in traceScanRootRes trace.c:528
>     #5 0x10650cec8 in TraceStart trace.c:1694
>     #6 0x106500fd8 in PolicyStartTrace policy.c:335
>     #7 0x106500544 in TracePoll trace.c:1840
>     #8 0x1064ec440 in ArenaPoll global.c:745
>     #9 0x1064ed30c in mps_ap_fill mpsi.c:1097
>     #10 0x10617d660 in alloc_impl igc.c:3954
>     #11 0x1061620c8 in alloc igc.c:3982
>     #12 0x106161f28 in igc_make_cons igc.c:4011
>     #13 0x105af5dc4 in Fcons alloc.c:2958
>     #254 0x105c6e8fc in Fprogn eval.c:452
...
> Address 0x00016ac1df20 is located in stack of thread T0 at offset 0 in frame
>     #0 0x10617d258 in alloc_impl igc.c:3945
>
>   This frame has 1 object(s):
>     [32, 40) 'p' (line 3946)
> HINT: this may be a false positive if your program uses some custom
> stack unwind mechanism, swapcontext or vfork
>       (longjmp and C++ exceptions *are* supported)
> SUMMARY: AddressSanitizer: stack-buffer-underflow igc.c:1552 in scan_ambig

I'm not quite sure what this is telling me. As I read it, we allocate a
cons, the allocation point needs memory (mps_ap_fill), and MPS triggers
scanning the C stack (scan_ambig).

  static mps_res_t
  scan_ambig (mps_ss_t ss, void *start, void *end, void *closure)
  {
    MPS_SCAN_BEGIN (ss)
    {
      for (mps_word_t *p = start; p < (mps_word_t *) end; ++p)
        {
          mps_word_t word = *p;

It seems the *p is somehow interpreted as underflowing a "buffer" in
alloc_impl's frame. What that buffer is that ASAN instrumented I can't
figure out ATM. Does it mean the C stack itself? If so, why doesn't it
say something about alloc_impl's frame? Questions upon questions.

> I'm not sure if ASan is supposed to be supported on this branch?

I have no idea either if ASAN is supposed to work with MPS or not.

> In any case, I had the idea to do the following,
>
> diff --git a/src/igc.c b/src/igc.c
> index 15db61e709d..9bc0eac970c 100644
> --- a/src/igc.c
> +++ b/src/igc.c
> @@ -1542,7 +1542,7 @@ scan_specpdl (mps_ss_t ss, void *start, void
> *end, void *closure)
>     references may be either tagged words or pointers.  This is used for
>     blocks allocated with malloc and thread stacks.  */
>
> -static mps_res_t
> +static mps_res_t ATTRIBUTE_NO_SANITIZE_ADDRESS
>  scan_ambig (mps_ss_t ss, void *start, void *end, void *closure)
>  {
>    MPS_SCAN_BEGIN (ss)
>
> but it seems like the ASan build still loses, currently with this
> repeated error while compiling emacs-lisp/radix-tree.elc:
>
> Re-entering top level after C stack overflow

So, maybe what I wrote above is kind of right, that we see a stack
overflow. Hm, there were some >250 or so frames in the backtrace. That's
a lot. And default stack size if 8 Mb on macOS, I think.

Does changing ulimit -s have some effect?





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#75482: scratch/igc: Building with ASan fails
  2025-01-10 22:04 bug#75482: scratch/igc: Building with ASan fails Stefan Kangas
  2025-01-11  4:22 ` Gerd Möllmann
@ 2025-01-11  5:20 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-01-11  5:53   ` Gerd Möllmann
  2025-01-12 10:53   ` Stefan Kangas
  1 sibling, 2 replies; 9+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-01-11  5:20 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 75482, gerd

"Stefan Kangas" <stefankangas@gmail.com> writes:

> I was experimenting with building the scratch/igc branch with
> -fsanitize=address, and I ran into this:

What kind of system is that on?

I'm not sure who added all the ASAN code to alloc.c, but we might want
to ask them whether it was worth it.

> =================================================================
> ==134==ERROR: AddressSanitizer: stack-buffer-underflow on address
> 0x00016ac1df20 at pc 0x00010617584c bp 0x00016ac1d690 sp
> 0x00016ac1d688
> READ of size 8 at 0x00016ac1df20 thread T0
>     #0 0x106175848 in scan_ambig igc.c:1552
>     #1 0x106529218 in StackScan ss.c:68
>     #2 0x10650e8a4 in ThreadScan thxc.c:242
>     #3 0x10650e46c in RootScan root.c
>     #4 0x10654ad88 in traceScanRootRes trace.c:528
>     #5 0x10650cec8 in TraceStart trace.c:1694
>     #6 0x106500fd8 in PolicyStartTrace policy.c:335
>     #7 0x106500544 in TracePoll trace.c:1840
>     #8 0x1064ec440 in ArenaPoll global.c:745
>     #9 0x1064ed30c in mps_ap_fill mpsi.c:1097
>     #10 0x10617d660 in alloc_impl igc.c:3954

AFAICT, what that says is that ASAN saw scan_ambig look at a parent's
stack frame; that is quite common in C (passing a pointer to a stack
variable to another function), so I assume ASAN has heuristics for
determining whether the pointer has been exposed to inner functions or
not.

In this case, the heuristic fails to determine that it's okay for
scan_ambig to look at stack frame #10.  I don't think that ASAN can be
fixed to recognize the peculiar case of a thread scanning its own stack
for conservative GC marking: if we want it to work, we need to add ASAN
calls in igc.c, just as we did in alloc.c.

I'm not in favor of doing that; there's a lot of ASAN-related noise in
alloc.c, and it makes reading that file difficult.  My impression is we
didn't find very many bugs by adding the ASAN code.  On the other hand,
igc.c isn't quite as complicated and there would be fewer calls.

>     #252 0x105c80f4c in FletX eval.c:1055
>     #253 0x105c69f28 in eval_sub eval.c:2564
>     #254 0x105c6e8fc in Fprogn eval.c:452

That's not the top of the stack; I assume ASAN just gave up when it hit
stack frame #255.  If ASAN can't give us complete stack traces, that's
another good reason not to use it.

> Address 0x00016ac1df20 is located in stack of thread T0 at offset 0 in frame
>     #0 0x10617d258 in alloc_impl igc.c:3945
>
>   This frame has 1 object(s):
>     [32, 40) 'p' (line 3946)
> HINT: this may be a false positive if your program uses some custom
> stack unwind mechanism, swapcontext or vfork
>       (longjmp and C++ exceptions *are* supported)

This hint doesn't say anything about our case; I guess you could call
conservative stacking a very special kind of stack unwinding.

> SUMMARY: AddressSanitizer: stack-buffer-underflow igc.c:1552 in scan_ambig
> Shadow bytes around the buggy address:
>   0x00016ac1dc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x00016ac1dd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x00016ac1dd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x00016ac1de00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x00016ac1de80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> =>0x00016ac1df00: 00 00 00 00[f1]f1 f1 f1 00 f3 f3 f3 00 00 00 00
>   0x00016ac1df80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x00016ac1e000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x00016ac1e080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x00016ac1e100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x00016ac1e180: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 f2 f2 f2
> Shadow byte legend (one shadow byte represents 8 application bytes):
>   Addressable:           00
>   Partially addressable: 01 02 03 04 05 06 07
>   Heap left redzone:       fa
>   Freed heap region:       fd
>   Stack left redzone:      f1
>   Stack mid redzone:       f2
>   Stack right redzone:     f3

That's very confusing: the term "red zone" usually refers to an area of
the stack on the wrong side of the stack pointer that leaf functions can
use without modifying the stack pointer because signal handlers will
leave it alone.

In this context, it's used for a guard region on the stack surrounding a
valid area.  That's totally different.

And no, I don't see any way for MPS to avoid scanning such guard
regions: we scan the entire C stack linearly.  The best we might be able
to do is to turn off ASAN for that part.

(I'm not sure GCC uses the real red zone on x86_64; if it does, we might
want to disable this "feature": red zones hide bugs, IME.)

> ==134==ABORTING

Is there an option to run ASAN without aborting on the first error?
valgrind is very good at grouping error messages by call stack, so it's
useful even if there are thousands of warnings.  (I'm not sure whether
valgrind would be a better fit than ASAN for Emacs, which has some
manual memory management but mostly relies on the GC).

> Fatal error 6: Aborted
> gmake[2]: *** [Makefile:1022: bootstrap-emacs.pdmp] Abort trap: 6
>
> I'm not sure if ASan is supposed to be supported on this branch?

The current code in scratch/igc does not support ASAN.

> In any case, I had the idea to do the following,
>
> diff --git a/src/igc.c b/src/igc.c
> index 15db61e709d..9bc0eac970c 100644
> --- a/src/igc.c
> +++ b/src/igc.c
> @@ -1542,7 +1542,7 @@ scan_specpdl (mps_ss_t ss, void *start, void
> *end, void *closure)
>     references may be either tagged words or pointers.  This is used for
>     blocks allocated with malloc and thread stacks.  */
>
> -static mps_res_t
> +static mps_res_t ATTRIBUTE_NO_SANITIZE_ADDRESS
>  scan_ambig (mps_ss_t ss, void *start, void *end, void *closure)
>  {
>    MPS_SCAN_BEGIN (ss)
>
> but it seems like the ASan build still loses, currently with this
> repeated error while compiling emacs-lisp/radix-tree.elc:
>
> Re-entering top level after C stack overflow

My impression from the above is that ASAN increases stack frame size a
lot: alloc_impl needs eight bytes of stack, but the f1/f2 zones require
an additional 56 bytes.  Building the initial ELC files uses a lot of
stack even with normal stack frames, and ASAN might push it over the
stack size limit.  Even on MS-DOS, b-emacs.exe gets 3072KB of stack, so
I think this is very likely.

I'm surprised the "Re-entering top level" message is printed at all, but
printing a message is probably all we can do when MPS is in use: on
GNU/Linux, we only reach handle_sigsegv after MPS has replaced its
signal handler, so the next memory barrier we hit will go straight to
handle_sigsegv, which will siglongjmp to return_to_command_loop again
(I'm not sure it's valid to perform two longjmps to the same jmpbuf,
making setjmp return a third time...)

Pip






^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#75482: scratch/igc: Building with ASan fails
  2025-01-11  4:22 ` Gerd Möllmann
@ 2025-01-11  5:41   ` Gerd Möllmann
  2025-01-12 10:22     ` Stefan Kangas
  0 siblings, 1 reply; 9+ messages in thread
From: Gerd Möllmann @ 2025-01-11  5:41 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 75482, gerd, pipcet

Gerd Möllmann <gerd.moellmann@gmail.com> writes:

/igc.c
>> index 15db61e709d..9bc0eac970c 100644
>> --- a/src/igc.c
>> +++ b/src/igc.c
>> @@ -1542,7 +1542,7 @@ scan_specpdl (mps_ss_t ss, void *start, void
>> *end, void *closure)
>>     references may be either tagged words or pointers.  This is used for
>>     blocks allocated with malloc and thread stacks.  */
>>
>> -static mps_res_t
>> +static mps_res_t ATTRIBUTE_NO_SANITIZE_ADDRESS
>>  scan_ambig (mps_ss_t ss, void *start, void *end, void *closure)
>>  {
>>    MPS_SCAN_BEGIN (ss)
>>
>> but it seems like the ASan build still loses, currently with this
>> repeated error while compiling emacs-lisp/radix-tree.elc:
>>
>> Re-entering top level after C stack overflow
>
> So, maybe what I wrote above is kind of right, that we see a stack
> overflow. Hm, there were some >250 or so frames in the backtrace. That's
> a lot. And default stack size if 8 Mb on macOS, I think.
>
> Does changing ulimit -s have some effect?

Tried this myself in my fork, with your patch + ulimit -s unlimited,
and it seems to work. 👍





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#75482: scratch/igc: Building with ASan fails
  2025-01-11  5:20 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-01-11  5:53   ` Gerd Möllmann
  2025-01-12 10:53   ` Stefan Kangas
  1 sibling, 0 replies; 9+ messages in thread
From: Gerd Möllmann @ 2025-01-11  5:53 UTC (permalink / raw)
  To: Pip Cet; +Cc: 75482, gerd, Stefan Kangas

Pip Cet <pipcet@protonmail.com> writes:

> I'm not in favor of doing that; there's a lot of ASAN-related noise in
> alloc.c, and it makes reading that file difficult.  My impression is we
> didn't find very many bugs by adding the ASAN code.  

I did. Some nasty stuff in NS, for example. And I think in the regexp
code too, IIRC. But of course all depends on what one makes of it, let me
only mention bug#73838 :-/.

>>   Stack right redzone:     f3
>
> That's very confusing: the term "red zone" usually refers to an area of
> the stack on the wrong side of the stack pointer that leaf functions can
> use without modifying the stack pointer because signal handlers will
> leave it alone.

I think that refers to what (clang) ASAN adds to buffers. If I have a
buffer [start end], then ASAN makes that [left][start end][right] to
detect writes/reads outside of the buffer. Something like that. I've
forgotten the details.





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#75482: scratch/igc: Building with ASan fails
  2025-01-11  5:41   ` Gerd Möllmann
@ 2025-01-12 10:22     ` Stefan Kangas
  0 siblings, 0 replies; 9+ messages in thread
From: Stefan Kangas @ 2025-01-12 10:22 UTC (permalink / raw)
  To: Gerd Möllmann; +Cc: gerd, 75482-done, pipcet

Gerd Möllmann <gerd.moellmann@gmail.com> writes:

> Tried this myself in my fork, with your patch + ulimit -s unlimited,
> and it seems to work. 👍

I was able to build after `ulimit -s unlimited`, so I installed the
patch.  I'm therefore closing this bug report.  Thanks!





^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#75482: scratch/igc: Building with ASan fails
  2025-01-11  5:20 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-01-11  5:53   ` Gerd Möllmann
@ 2025-01-12 10:53   ` Stefan Kangas
  2025-01-12 11:02     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 9+ messages in thread
From: Stefan Kangas @ 2025-01-12 10:53 UTC (permalink / raw)
  To: Pip Cet; +Cc: 75482, gerd

[-- Attachment #1: Type: text/plain, Size: 3263 bytes --]

Pip Cet <pipcet@protonmail.com> writes:

> "Stefan Kangas" <stefankangas@gmail.com> writes:
>
>> I was experimenting with building the scratch/igc branch with
>> -fsanitize=address, and I ran into this:
>
> What kind of system is that on?

Sorry for the late reply here.  This is macOS, compiling with

    ./configure --with-mps --enable-checking="yes,igc_debug" \
    --enable-check-lisp-object-type \
    CFLAGS="$CFLAGS -O0 -g3 -fsanitize=address"

>> =================================================================
>> ==134==ERROR: AddressSanitizer: stack-buffer-underflow on address
>> 0x00016ac1df20 at pc 0x00010617584c bp 0x00016ac1d690 sp
>> 0x00016ac1d688
>> READ of size 8 at 0x00016ac1df20 thread T0
>>     #0 0x106175848 in scan_ambig igc.c:1552
>>     #1 0x106529218 in StackScan ss.c:68
>>     #2 0x10650e8a4 in ThreadScan thxc.c:242
>>     #3 0x10650e46c in RootScan root.c
>>     #4 0x10654ad88 in traceScanRootRes trace.c:528
>>     #5 0x10650cec8 in TraceStart trace.c:1694
>>     #6 0x106500fd8 in PolicyStartTrace policy.c:335
>>     #7 0x106500544 in TracePoll trace.c:1840
>>     #8 0x1064ec440 in ArenaPoll global.c:745
>>     #9 0x1064ed30c in mps_ap_fill mpsi.c:1097
>>     #10 0x10617d660 in alloc_impl igc.c:3954
>
> AFAICT, what that says is that ASAN saw scan_ambig look at a parent's
> stack frame; that is quite common in C (passing a pointer to a stack
> variable to another function), so I assume ASAN has heuristics for
> determining whether the pointer has been exposed to inner functions or
> not.
>
> In this case, the heuristic fails to determine that it's okay for
> scan_ambig to look at stack frame #10.  I don't think that ASAN can be
> fixed to recognize the peculiar case of a thread scanning its own stack
> for conservative GC marking: if we want it to work, we need to add ASAN
> calls in igc.c, just as we did in alloc.c.

The patch I just installed simply makes ASan ignore that we are scanning
bytes in its redzone on the stack, which seems to be all that was needed
to get the build to work.

> I'm not in favor of doing that; there's a lot of ASAN-related noise in
> alloc.c, and it makes reading that file difficult.  My impression is we
> didn't find very many bugs by adding the ASAN code.  On the other hand,
> igc.c isn't quite as complicated and there would be fewer calls.

I hope that it will be easier to get igc to work with ASan.  We'll see.

>>     #252 0x105c80f4c in FletX eval.c:1055
>>     #253 0x105c69f28 in eval_sub eval.c:2564
>>     #254 0x105c6e8fc in Fprogn eval.c:452
>
> That's not the top of the stack; I assume ASAN just gave up when it hit
> stack frame #255.  If ASAN can't give us complete stack traces, that's
> another good reason not to use it.

I was able to get a complete backtrace if I did

    export ASAN_OPTIONS=abort_on_error=1
    lldb src/emacs-bootstrap

Then I could run "bt all" as usual.  You can also use breakpoints, as
explained here
https://github.com/google/sanitizers/wiki/AddressSanitizerAndDebugger

I've attached the result of doing that, for reference, but I don't think
it contained anything too interesting.  The problem is that we're
necessarily trying to scan the stack, and ASan doesn't understand that
it's fine (at least not before my patch).

[-- Attachment #2: backtrace.txt --]
[-- Type: text/plain, Size: 34285 bytes --]

$ export ASAN_OPTIONS=abort_on_error=1
$ lldb bootstrap-emacs     
(lldb) target create "bootstrap-emacs"
Current executable set to '/Users/stefan/wip/emacs/src/bootstrap-emacs' (arm64).
(lldb) run
Process 91296 launched: '/Users/stefan/wip/emacs/src/bootstrap-emacs' (arm64)
2025-01-11 17:00:14.596168+0100 bootstrap-emacs[91296:12377160] +[IMKClient subclass]: chose IMKClient_Modern
2025-01-11 17:00:14.596200+0100 bootstrap-emacs[91296:12377160] +[IMKInputSession subclass]: chose IMKInputSession_Modern
=================================================================
==91296==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x00016fd91180 at pc 0x0001012057ec bp 0x00016fd908f0 sp 0x00016fd908e8
READ of size 8 at 0x00016fd91180 thread T0
    #0 0x1012057e8 in scan_ambig igc.c:1552
    #1 0x1015b91b8 in StackScan ss.c:68
    #2 0x10159e844 in ThreadScan thxc.c:242
    #3 0x10159e40c in RootScan root.c
    #4 0x1015dad28 in traceScanRootRes trace.c:528
    #5 0x10159ce68 in TraceStart trace.c:1694
    #6 0x101590f78 in PolicyStartTrace policy.c:335
    #7 0x1015904e4 in TracePoll trace.c:1840
    #8 0x10157c3e0 in ArenaPoll global.c:745
    #9 0x10157d2ac in mps_ap_fill mpsi.c:1097
    #10 0x10120d600 in alloc_impl igc.c:3954
    #11 0x1011f2068 in alloc igc.c:3982
    #12 0x1011f2bf8 in igc_alloc_bytes igc.c:4045
    #13 0x100b9352c in hash_table_alloc_bytes alloc.c:5845
    #14 0x100dc52d4 in maybe_resize_hash_table fns.c:5030
    #15 0x100dc4878 in hash_put fns.c:5268
    #16 0x100620048 in hash_get_category_set category.c:60
    #17 0x10061eb64 in Fmodify_category_entry category.c:364
    #18 0x100d375e8 in funcall_subr eval.c:3182
    #19 0x100f9a460 in exec_byte_code bytecode.c:828
    #20 0x100f94cf8 in Fbyte_code bytecode.c:325
    #21 0x100cfa9dc in eval_sub eval.c:2619
    #22 0x100ee1444 in readevalloop lread.c:2540
    #23 0x100ed201c in Fload lread.c:1728
    #24 0x100ee20e8 in save_match_data_load lread.c:1780
    #25 0x100d2c690 in load_with_autoload_queue eval.c:2392
    #26 0x100db19c0 in Frequire fns.c:3809
    #27 0x100d37424 in funcall_subr eval.c:3180
    #28 0x100f9a460 in exec_byte_code bytecode.c:828
    #29 0x100f94cf8 in Fbyte_code bytecode.c:325
    #30 0x100cfa9dc in eval_sub eval.c:2619
    #31 0x100ee1444 in readevalloop lread.c:2540
    #32 0x100ed201c in Fload lread.c:1728
    #33 0x100ee20e8 in save_match_data_load lread.c:1780
    #34 0x100d2c690 in load_with_autoload_queue eval.c:2392
    #35 0x100db19c0 in Frequire fns.c:3809
    #36 0x100d37424 in funcall_subr eval.c:3180
    #37 0x100f9a460 in exec_byte_code bytecode.c:828
    #38 0x100f94cf8 in Fbyte_code bytecode.c:325
    #39 0x100cfa9dc in eval_sub eval.c:2619
    #40 0x100ee1444 in readevalloop lread.c:2540
    #41 0x100ed201c in Fload lread.c:1728
    #42 0x100ee20e8 in save_match_data_load lread.c:1780
    #43 0x100d2c690 in load_with_autoload_queue eval.c:2392
    #44 0x100db19c0 in Frequire fns.c:3809
    #45 0x100d37424 in funcall_subr eval.c:3180
    #46 0x100f9a460 in exec_byte_code bytecode.c:828
    #47 0x100f94cf8 in Fbyte_code bytecode.c:325
    #48 0x100cfa9dc in eval_sub eval.c:2619
    #49 0x100ee1444 in readevalloop lread.c:2540
    #50 0x100ed201c in Fload lread.c:1728
    #51 0x100ee20e8 in save_match_data_load lread.c:1780
    #52 0x100d2c690 in load_with_autoload_queue eval.c:2392
    #53 0x100db19c0 in Frequire fns.c:3809
    #54 0x100cfa9dc in eval_sub eval.c:2619
    #55 0x100cfe220 in Fprogn eval.c:452
    #56 0x100cf984c in eval_sub eval.c:2564
    #57 0x100d2d890 in Feval eval.c:2472
    #58 0x100d372b0 in funcall_subr eval.c:3178
    #59 0x100f9a460 in exec_byte_code bytecode.c:828
    #60 0x100d39040 in funcall_lambda eval.c:3267
    #61 0x100d36160 in funcall_general eval.c:3059
    #62 0x100d05504 in Ffuncall eval.c:3108
    #63 0x100d30aa4 in Fapply eval.c:2737
    #64 0x100cf5ddc in apply1 eval.c:2996
    #65 0x100d169c4 in Fmacroexpand eval.c:1248
    #66 0x100d372b0 in funcall_subr eval.c:3178
    #67 0x100d35ff4 in funcall_general eval.c:3055
    #68 0x100d05504 in Ffuncall eval.c:3108
    #69 0x105059e74 in F696e7465726e616c2d6d6163726f657870616e642d666f722d6c6f6164_internal_macroexpand_for_load_0+0x594 (macroexp-2c3e1495-c0b1cf80.eln:arm64+0x9e74)
    #70 0x100d372b0 in funcall_subr eval.c:3178
    #71 0x100d35ff4 in funcall_general eval.c:3055
    #72 0x100d05504 in Ffuncall eval.c:3108
    #73 0x100f1d4bc in readevalloop_eager_expand_eval lread.c:2347
    #74 0x100ee139c in readevalloop lread.c:2538
    #75 0x100ee7c68 in Feval_buffer lread.c:2613
    #76 0x119e9f0f0 in F6c6f61642d776974682d636f64652d636f6e76657273696f6e_load_with_code_conversion_0+0x310 (mule-3352613d-d3b3728f.eln:arm64+0x30f0)
    #77 0x100d377fc in funcall_subr eval.c:3184
    #78 0x100d35ff4 in funcall_general eval.c:3055
    #79 0x100d05504 in Ffuncall eval.c:3108
    #80 0x100ed0bc4 in Fload lread.c:1616
    #81 0x100ee20e8 in save_match_data_load lread.c:1780
    #82 0x100d2c690 in load_with_autoload_queue eval.c:2392
    #83 0x100d17d40 in Fautoload_do_load eval.c:2438
    #84 0x100cfbf08 in eval_sub eval.c:2672
    #85 0x100f1de14 in readevalloop_eager_expand_eval lread.c:2356
    #86 0x100ee139c in readevalloop lread.c:2538
    #87 0x100ee7c68 in Feval_buffer lread.c:2613
    #88 0x119e9f0f0 in F6c6f61642d776974682d636f64652d636f6e76657273696f6e_load_with_code_conversion_0+0x310 (mule-3352613d-d3b3728f.eln:arm64+0x30f0)
    #89 0x100d377fc in funcall_subr eval.c:3184
    #90 0x100d35ff4 in funcall_general eval.c:3055
    #91 0x100d05504 in Ffuncall eval.c:3108
    #92 0x100ed0bc4 in Fload lread.c:1616
    #93 0x100ee20e8 in save_match_data_load lread.c:1780
    #94 0x100d2c690 in load_with_autoload_queue eval.c:2392
    #95 0x100db19c0 in Frequire fns.c:3809
    #96 0x100cfa9dc in eval_sub eval.c:2619
    #97 0x100f1de14 in readevalloop_eager_expand_eval lread.c:2356
    #98 0x100ee139c in readevalloop lread.c:2538
    #99 0x100ee7c68 in Feval_buffer lread.c:2613
    #100 0x119e9f0f0 in F6c6f61642d776974682d636f64652d636f6e76657273696f6e_load_with_code_conversion_0+0x310 (mule-3352613d-d3b3728f.eln:arm64+0x30f0)
    #101 0x100d377fc in funcall_subr eval.c:3184
    #102 0x100d35ff4 in funcall_general eval.c:3055
    #103 0x100d05504 in Ffuncall eval.c:3108
    #104 0x100ed0bc4 in Fload lread.c:1616
    #105 0x100d377fc in funcall_subr eval.c:3184
    #106 0x100f9a460 in exec_byte_code bytecode.c:828
    #107 0x100d39040 in funcall_lambda eval.c:3267
    #108 0x100d36160 in funcall_general eval.c:3059
    #109 0x100d05504 in Ffuncall eval.c:3108
    #110 0x11a19e6a4 in F737461727475702d2d6c6f61642d757365722d696e69742d66696c65_startup__load_user_init_file_0+0x2fc (startup-bbc6ea72-6643f97a.eln:arm64+0x66a4)
    #111 0x100d37424 in funcall_subr eval.c:3180
    #112 0x100d35ff4 in funcall_general eval.c:3055
    #113 0x100d05504 in Ffuncall eval.c:3108
    #114 0x11a19fdb4 in F636f6d6d616e642d6c696e65_command_line_0+0x124c (startup-bbc6ea72-6643f97a.eln:arm64+0x7db4)
    #115 0x100d370b8 in funcall_subr eval.c:3174
    #116 0x100d35ff4 in funcall_general eval.c:3055
    #117 0x100d05504 in Ffuncall eval.c:3108
    #118 0x11a19cb28 in F6e6f726d616c2d746f702d6c6576656c_normal_top_level_0+0xe60 (startup-bbc6ea72-6643f97a.eln:arm64+0x4b28)
    #119 0x100cfa58c in eval_sub eval.c:2610
    #120 0x100d2d890 in Feval eval.c:2472
    #121 0x10083daac in top_level_2 keyboard.c:1190
    #122 0x100d1e968 in internal_condition_case eval.c:1627
    #123 0x10083d3c8 in top_level_1 keyboard.c:1202
    #124 0x100d18bf8 in internal_catch eval.c:1306
    #125 0x1007a99d0 in command_loop keyboard.c:1151
    #126 0x1007a8b00 in recursive_edit_1 keyboard.c:760
    #127 0x1007ab0fc in Frecursive_edit keyboard.c:843
    #128 0x10079939c in main emacs.c:2658
    #129 0x18ddec270  (<unknown module>)

Address 0x00016fd91180 is located in stack of thread T0 at offset 0 in frame
    #0 0x10120d1f8 in alloc_impl igc.c:3945

  This frame has 1 object(s):
    [32, 40) 'p' (line 3946)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-underflow igc.c:1552 in scan_ambig
Shadow bytes around the buggy address:
  0x00016fd90f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00016fd90f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00016fd91000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00016fd91080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00016fd91100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x00016fd91180:[f1]f1 f1 f1 00 f3 f3 f3 00 00 00 00 00 00 00 00
  0x00016fd91200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00016fd91280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00016fd91300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00016fd91380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00016fd91400: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==91296==ABORTING
(lldb) AddressSanitizer report breakpoint hit. Use 'thread info -s' to get extended information about the report.
Process 91296 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = Stack buffer underflow
    frame #0: 0x0000000102e6d060 libclang_rt.asan_osx_dynamic.dylib`__asan::AsanDie()
libclang_rt.asan_osx_dynamic.dylib`__asan::AsanDie:
->  0x102e6d060 <+0>:  pacibsp 
    0x102e6d064 <+4>:  stp    x20, x19, [sp, #-0x20]!
    0x102e6d068 <+8>:  stp    x29, x30, [sp, #0x10]
    0x102e6d06c <+12>: add    x29, sp, #0x10
Target 0: (bootstrap-emacs) stopped.
error: This version of LLDB does not support DWARF version 5 or later.
(lldb) bt all
* thread #1, queue = 'com.apple.main-thread', stop reason = Stack buffer underflow
  * frame #0: 0x0000000102e6d060 libclang_rt.asan_osx_dynamic.dylib`__asan::AsanDie()
    frame #1: 0x0000000102e86e24 libclang_rt.asan_osx_dynamic.dylib`__sanitizer::Die() + 192
    frame #2: 0x0000000102e6af54 libclang_rt.asan_osx_dynamic.dylib`__asan::ScopedInErrorReport::~ScopedInErrorReport() + 1124
    frame #3: 0x0000000102e6a22c libclang_rt.asan_osx_dynamic.dylib`__asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) + 1460
    frame #4: 0x0000000102e6b748 libclang_rt.asan_osx_dynamic.dylib`__asan_report_load8 + 56
    frame #5: 0x00000001012057ec bootstrap-emacs`scan_ambig(ss=0x000000016fd90e18, start=0x000000016fd91058, end=0x000000016fdfda40, closure=0x0000000000000000) at igc.c:1552:20
    frame #6: 0x00000001015b91bc bootstrap-emacs`StackScan
    frame #7: 0x000000010159e848 bootstrap-emacs`ThreadScan
    frame #8: 0x000000010159e410 bootstrap-emacs`RootScan
    frame #9: 0x00000001015dad2c bootstrap-emacs`traceScanRootRes
    frame #10: 0x000000010159ce6c bootstrap-emacs`TraceStart
    frame #11: 0x0000000101590f7c bootstrap-emacs`PolicyStartTrace
    frame #12: 0x00000001015904e8 bootstrap-emacs`TracePoll
    frame #13: 0x000000010157c3e4 bootstrap-emacs`ArenaPoll
    frame #14: 0x000000010157d2b0 bootstrap-emacs`mps_ap_fill
    frame #15: 0x000000010120d604 bootstrap-emacs`alloc_impl(size=3080, type=IGC_OBJ_STRING_DATA, ap=0x0000000109b69a18) at igc.c:3954:20
    frame #16: 0x00000001011f206c bootstrap-emacs`alloc(size=3080, type=IGC_OBJ_STRING_DATA) at igc.c:3982:10
    frame #17: 0x00000001011f2bfc bootstrap-emacs`igc_alloc_bytes(nbytes=3072) at igc.c:4045:5
    frame #18: 0x0000000100b93530 bootstrap-emacs`hash_table_alloc_bytes(nbytes=3072) at alloc.c:5845:13
    frame #19: 0x0000000100dc52d8 bootstrap-emacs`maybe_resize_hash_table(h=0x0000000109f23e08) at fns.c:5030:27
    frame #20: 0x0000000100dc487c bootstrap-emacs`hash_put(h=0x0000000109f23e08, key=(i = 0x000000011216124d), value=(i = 0x0000000000000000), hash=561158) at fns.c:5268:3
    frame #21: 0x000000010062004c bootstrap-emacs`hash_get_category_set(table=(i = 0x0000000109f23bcd), category_set=(i = 0x000000011216124d)) at category.c:60:3
    frame #22: 0x000000010061eb68 bootstrap-emacs`Fmodify_category_entry(character=(i = 0x0000000000000086), category=(i = 0x00000000000000fa), table=(i = 0x0000000109f23bcd), reset=(i = 0x0000000000000000)) at category.c:364:19
    frame #23: 0x0000000100d375ec bootstrap-emacs`funcall_subr(subr=0x0000000101ef8080, numargs=2, args=0x000000011ad04a20) at eval.c:3182:15
    frame #24: 0x0000000100f9a464 bootstrap-emacs`exec_byte_code(fun=(i = 0x00000001121605ad), args_template=0, nargs=0, args=0x0000000000000000) at bytecode.c:828:14
    frame #25: 0x0000000100f94cfc bootstrap-emacs`Fbyte_code(bytestr=(i = 0x00000001121602ac), vector=(i = 0x00000001121604f5), maxdepth=(i = 0x0000000000000022)) at bytecode.c:325:10
    frame #26: 0x0000000100cfa9e0 bootstrap-emacs`eval_sub(form=(i = 0x0000000112160293)) at eval.c:2619:15
    frame #27: 0x0000000100ee1448 bootstrap-emacs`readevalloop(readcharfun=(i = 0x000000000000a410), infile0=0x000000016fd9d220, sourcename=(i = 0x000000011215b94c), printflag=false, unibyte=(i = 0x0000000000000000), readfun=(i = 0x0000000000000000), start=(i = 0x0000000000000000), end=(i = 0x0000000000000000)) at lread.c:2540:15
    frame #28: 0x0000000100ed2020 bootstrap-emacs`Fload(file=(i = 0x0000000109cd68dc), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at lread.c:1728:9
    frame #29: 0x0000000100ee20ec bootstrap-emacs`save_match_data_load(file=(i = 0x0000000109cd68dc), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at lread.c:1780:24
    frame #30: 0x0000000100d2c694 bootstrap-emacs`load_with_autoload_queue(file=(i = 0x0000000109cd68dc), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at eval.c:2392:7
    frame #31: 0x0000000100db19c4 bootstrap-emacs`Frequire(feature=(i = 0x0000000007bdfd58), filename=(i = 0x0000000000000000), noerror=(i = 0x0000000000000000)) at fns.c:3809:13
    frame #32: 0x0000000100d37428 bootstrap-emacs`funcall_subr(subr=0x0000000101f0f980, numargs=1, args=0x000000011ad049a0) at eval.c:3180:15
    frame #33: 0x0000000100f9a464 bootstrap-emacs`exec_byte_code(fun=(i = 0x000000011213a3ed), args_template=0, nargs=0, args=0x0000000000000000) at bytecode.c:828:14
    frame #34: 0x0000000100f94cfc bootstrap-emacs`Fbyte_code(bytestr=(i = 0x0000000112139f44), vector=(i = 0x000000011213a31d), maxdepth=(i = 0x0000000000000022)) at bytecode.c:325:10
    frame #35: 0x0000000100cfa9e0 bootstrap-emacs`eval_sub(form=(i = 0x0000000112139f2b)) at eval.c:2619:15
    frame #36: 0x0000000100ee1448 bootstrap-emacs`readevalloop(readcharfun=(i = 0x000000000000a410), infile0=0x000000016fdaad60, sourcename=(i = 0x0000000112139704), printflag=false, unibyte=(i = 0x0000000000000000), readfun=(i = 0x0000000000000000), start=(i = 0x0000000000000000), end=(i = 0x0000000000000000)) at lread.c:2540:15
    frame #37: 0x0000000100ed2020 bootstrap-emacs`Fload(file=(i = 0x000000010d2db28c), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at lread.c:1728:9
    frame #38: 0x0000000100ee20ec bootstrap-emacs`save_match_data_load(file=(i = 0x000000010d2db28c), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at lread.c:1780:24
    frame #39: 0x0000000100d2c694 bootstrap-emacs`load_with_autoload_queue(file=(i = 0x000000010d2db28c), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at eval.c:2392:7
    frame #40: 0x0000000100db19c4 bootstrap-emacs`Frequire(feature=(i = 0x000000000b1e4830), filename=(i = 0x0000000000000000), noerror=(i = 0x0000000000000000)) at fns.c:3809:13
    frame #41: 0x0000000100d37428 bootstrap-emacs`funcall_subr(subr=0x0000000101f0f980, numargs=1, args=0x000000011ad04940) at eval.c:3180:15
    frame #42: 0x0000000100f9a464 bootstrap-emacs`exec_byte_code(fun=(i = 0x000000011209be95), args_template=0, nargs=0, args=0x0000000000000000) at bytecode.c:828:14
    frame #43: 0x0000000100f94cfc bootstrap-emacs`Fbyte_code(bytestr=(i = 0x000000011209909c), vector=(i = 0x000000011209bb55), maxdepth=(i = 0x0000000000000022)) at bytecode.c:325:10
    frame #44: 0x0000000100cfa9e0 bootstrap-emacs`eval_sub(form=(i = 0x0000000112099083)) at eval.c:2619:15
    frame #45: 0x0000000100ee1448 bootstrap-emacs`readevalloop(readcharfun=(i = 0x000000000000a410), infile0=0x000000016fdb88a0, sourcename=(i = 0x00000001120987e4), printflag=false, unibyte=(i = 0x0000000000000000), readfun=(i = 0x0000000000000000), start=(i = 0x0000000000000000), end=(i = 0x0000000000000000)) at lread.c:2540:15
    frame #46: 0x0000000100ed2020 bootstrap-emacs`Fload(file=(i = 0x000000010d324814), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at lread.c:1728:9
    frame #47: 0x0000000100ee20ec bootstrap-emacs`save_match_data_load(file=(i = 0x000000010d324814), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at lread.c:1780:24
    frame #48: 0x0000000100d2c694 bootstrap-emacs`load_with_autoload_queue(file=(i = 0x000000010d324814), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at eval.c:2392:7
    frame #49: 0x0000000100db19c4 bootstrap-emacs`Frequire(feature=(i = 0x000000000b22ddb8), filename=(i = 0x0000000000000000), noerror=(i = 0x0000000000000000)) at fns.c:3809:13
    frame #50: 0x0000000100d37428 bootstrap-emacs`funcall_subr(subr=0x0000000101f0f980, numargs=1, args=0x000000011ad048c0) at eval.c:3180:15
    frame #51: 0x0000000100f9a464 bootstrap-emacs`exec_byte_code(fun=(i = 0x00000001119f8f4d), args_template=0, nargs=0, args=0x0000000000000000) at bytecode.c:828:14
    frame #52: 0x0000000100f94cfc bootstrap-emacs`Fbyte_code(bytestr=(i = 0x00000001119f269c), vector=(i = 0x00000001119f8c4d), maxdepth=(i = 0x0000000000000032)) at bytecode.c:325:10
    frame #53: 0x0000000100cfa9e0 bootstrap-emacs`eval_sub(form=(i = 0x00000001119f2683)) at eval.c:2619:15
    frame #54: 0x0000000100ee1448 bootstrap-emacs`readevalloop(readcharfun=(i = 0x000000000000a410), infile0=0x000000016fdc63e0, sourcename=(i = 0x00000001119f1de4), printflag=false, unibyte=(i = 0x0000000000000000), readfun=(i = 0x0000000000000000), start=(i = 0x0000000000000000), end=(i = 0x0000000000000000)) at lread.c:2540:15
    frame #55: 0x0000000100ed2020 bootstrap-emacs`Fload(file=(i = 0x000000010d2e0184), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at lread.c:1728:9
    frame #56: 0x0000000100ee20ec bootstrap-emacs`save_match_data_load(file=(i = 0x000000010d2e0184), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at lread.c:1780:24
    frame #57: 0x0000000100d2c694 bootstrap-emacs`load_with_autoload_queue(file=(i = 0x000000010d2e0184), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at eval.c:2392:7
    frame #58: 0x0000000100db19c4 bootstrap-emacs`Frequire(feature=(i = 0x000000000b1e9728), filename=(i = 0x0000000000000000), noerror=(i = 0x0000000000000000)) at fns.c:3809:13
    frame #59: 0x0000000100cfa9e0 bootstrap-emacs`eval_sub(form=(i = 0x00000001119d43c3)) at eval.c:2619:15
    frame #60: 0x0000000100cfe224 bootstrap-emacs`Fprogn(body=(i = 0x0000000000000000)) at eval.c:452:13
    frame #61: 0x0000000100cf9850 bootstrap-emacs`eval_sub(form=(i = 0x00000001119d446b)) at eval.c:2564:8
    frame #62: 0x0000000100d2d894 bootstrap-emacs`Feval(form=(i = 0x00000001119d446b), lexical=(i = 0x0000000000000038)) at eval.c:2472:28
    frame #63: 0x0000000100d372b4 bootstrap-emacs`funcall_subr(subr=0x0000000101f0b800, numargs=2, args=0x000000011ad04888) at eval.c:3178:15
    frame #64: 0x0000000100f9a464 bootstrap-emacs`exec_byte_code(fun=(i = 0x000000010a83b125), args_template=128, nargs=1, args=0x000000016fdd5628) at bytecode.c:828:14
    frame #65: 0x0000000100d39044 bootstrap-emacs`funcall_lambda(fun=(i = 0x000000010a83b125), nargs=1, arg_vector=0x000000016fdd5628) at eval.c:3267:9
    frame #66: 0x0000000100d36164 bootstrap-emacs`funcall_general(fun=(i = 0x000000010a83b125), numargs=1, args=0x000000016fdd5628) at eval.c:3059:12
    frame #67: 0x0000000100d05508 bootstrap-emacs`Ffuncall(nargs=2, args=0x000000016fdd5620) at eval.c:3108:21
    frame #68: 0x0000000100d30aa8 bootstrap-emacs`Fapply(nargs=2, args=0x000000016fdd5620) at eval.c:2737:14
    frame #69: 0x0000000100cf5de0 bootstrap-emacs`apply1(fn=(i = 0x000000010a83b125), arg=(i = 0x00000001119d4423)) at eval.c:2996:43
    frame #70: 0x0000000100d169c8 bootstrap-emacs`Fmacroexpand(form=(i = 0x00000001119d43ab), environment=(i = 0x0000000000000000)) at eval.c:1248:24
    frame #71: 0x0000000100d372b4 bootstrap-emacs`funcall_subr(subr=0x0000000101f0b300, numargs=1, args=0x000000016fdd70c0) at eval.c:3178:15
    frame #72: 0x0000000100d35ff8 bootstrap-emacs`funcall_general(fun=(i = 0x0000000101f0b305), numargs=1, args=0x000000016fdd70c0) at eval.c:3055:12
    frame #73: 0x0000000100d05508 bootstrap-emacs`Ffuncall(nargs=2, args=0x000000016fdd70b8) at eval.c:3108:21
    frame #74: 0x0000000105059e78 macroexp-2c3e1495-c0b1cf80.eln`F696e7465726e616c2d6d6163726f657870616e642d666f722d6c6f6164_internal_macroexpand_for_load_0 + 1432
    frame #75: 0x0000000100d372b4 bootstrap-emacs`funcall_subr(subr=0x000000010a8f5798, numargs=2, args=0x000000016fdd84e8) at eval.c:3178:15
    frame #76: 0x0000000100d35ff8 bootstrap-emacs`funcall_general(fun=(i = 0x000000010a8f579d), numargs=2, args=0x000000016fdd84e8) at eval.c:3055:12
    frame #77: 0x0000000100d05508 bootstrap-emacs`Ffuncall(nargs=3, args=0x000000016fdd84e0) at eval.c:3108:21
    frame #78: 0x0000000100f1d4c0 bootstrap-emacs`readevalloop_eager_expand_eval(val=(i = 0x00000001119d43ab), macroexpand=(i = 0x000000000000c3c8)) at lread.c:2347:9
    frame #79: 0x0000000100ee13a0 bootstrap-emacs`readevalloop(readcharfun=(i = 0x000000011167c005), infile0=0x0000000000000000, sourcename=(i = 0x000000011167bcfc), printflag=false, unibyte=(i = 0x0000000000000000), readfun=(i = 0x0000000000000000), start=(i = 0x0000000000000000), end=(i = 0x0000000000000000)) at lread.c:2538:15
    frame #80: 0x0000000100ee7c6c bootstrap-emacs`Feval_buffer(buffer=(i = 0x000000011167c005), printflag=(i = 0x0000000000000000), filename=(i = 0x000000011167bcfc), unibyte=(i = 0x0000000000000000), do_allow_print=(i = 0x0000000000000038)) at lread.c:2613:3
    frame #81: 0x0000000119e9f0f4 mule-3352613d-d3b3728f.eln`F6c6f61642d776974682d636f64652d636f6e76657273696f6e_load_with_code_conversion_0 + 788
    frame #82: 0x0000000100d37800 bootstrap-emacs`funcall_subr(subr=0x000000010a0fdaa0, numargs=4, args=0x000000016fddc818) at eval.c:3184:15
    frame #83: 0x0000000100d35ff8 bootstrap-emacs`funcall_general(fun=(i = 0x000000010a0fdaa5), numargs=4, args=0x000000016fddc818) at eval.c:3055:12
    frame #84: 0x0000000100d05508 bootstrap-emacs`Ffuncall(nargs=5, args=0x000000016fddc810) at eval.c:3108:21
    frame #85: 0x0000000100ed0bc8 bootstrap-emacs`Fload(file=(i = 0x0000000109e8853c), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at lread.c:1616:10
    frame #86: 0x0000000100ee20ec bootstrap-emacs`save_match_data_load(file=(i = 0x0000000109e8853c), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at lread.c:1780:24
    frame #87: 0x0000000100d2c694 bootstrap-emacs`load_with_autoload_queue(file=(i = 0x0000000109e8853c), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at eval.c:2392:7
    frame #88: 0x0000000100d17d44 bootstrap-emacs`Fautoload_do_load(fundef=(i = 0x000000010a76ee23), funname=(i = 0x0000000008678368), macro_only=(i = 0x0000000000000000)) at eval.c:2438:3
    frame #89: 0x0000000100cfbf0c bootstrap-emacs`eval_sub(form=(i = 0x000000011167adbb)) at eval.c:2672:4
    frame #90: 0x0000000100f1de18 bootstrap-emacs`readevalloop_eager_expand_eval(val=(i = 0x000000011167adbb), macroexpand=(i = 0x000000000000c3c8)) at lread.c:2356:13
    frame #91: 0x0000000100ee13a0 bootstrap-emacs`readevalloop(readcharfun=(i = 0x0000000111660005), infile0=0x0000000000000000, sourcename=(i = 0x000000011165bd04), printflag=false, unibyte=(i = 0x0000000000000000), readfun=(i = 0x0000000000000000), start=(i = 0x0000000000000000), end=(i = 0x0000000000000000)) at lread.c:2538:15
    frame #92: 0x0000000100ee7c6c bootstrap-emacs`Feval_buffer(buffer=(i = 0x0000000111660005), printflag=(i = 0x0000000000000000), filename=(i = 0x000000011165bd04), unibyte=(i = 0x0000000000000000), do_allow_print=(i = 0x0000000000000038)) at lread.c:2613:3
    frame #93: 0x0000000119e9f0f4 mule-3352613d-d3b3728f.eln`F6c6f61642d776974682d636f64652d636f6e76657273696f6e_load_with_code_conversion_0 + 788
    frame #94: 0x0000000100d37800 bootstrap-emacs`funcall_subr(subr=0x000000010a0fdaa0, numargs=4, args=0x000000016fde5178) at eval.c:3184:15
    frame #95: 0x0000000100d35ff8 bootstrap-emacs`funcall_general(fun=(i = 0x000000010a0fdaa5), numargs=4, args=0x000000016fde5178) at eval.c:3055:12
    frame #96: 0x0000000100d05508 bootstrap-emacs`Ffuncall(nargs=5, args=0x000000016fde5170) at eval.c:3108:21
    frame #97: 0x0000000100ed0bc8 bootstrap-emacs`Fload(file=(i = 0x00000001116442c4), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at lread.c:1616:10
    frame #98: 0x0000000100ee20ec bootstrap-emacs`save_match_data_load(file=(i = 0x00000001116442c4), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at lread.c:1780:24
    frame #99: 0x0000000100d2c694 bootstrap-emacs`load_with_autoload_queue(file=(i = 0x00000001116442c4), noerror=(i = 0x0000000000000000), nomessage=(i = 0x0000000000000038), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000038)) at eval.c:2392:7
    frame #100: 0x0000000100db19c4 bootstrap-emacs`Frequire(feature=(i = 0x000000000f54d868), filename=(i = 0x0000000000000000), noerror=(i = 0x0000000000000000)) at fns.c:3809:13
    frame #101: 0x0000000100cfa9e0 bootstrap-emacs`eval_sub(form=(i = 0x00000001116442ab)) at eval.c:2619:15
    frame #102: 0x0000000100f1de18 bootstrap-emacs`readevalloop_eager_expand_eval(val=(i = 0x00000001116442ab), macroexpand=(i = 0x000000000000c3c8)) at lread.c:2356:13
    frame #103: 0x0000000100ee13a0 bootstrap-emacs`readevalloop(readcharfun=(i = 0x000000010bec2425), infile0=0x0000000000000000, sourcename=(i = 0x000000010bec231c), printflag=false, unibyte=(i = 0x0000000000000000), readfun=(i = 0x0000000000000000), start=(i = 0x0000000000000000), end=(i = 0x0000000000000000)) at lread.c:2538:15
    frame #104: 0x0000000100ee7c6c bootstrap-emacs`Feval_buffer(buffer=(i = 0x000000010bec2425), printflag=(i = 0x0000000000000000), filename=(i = 0x000000010bec231c), unibyte=(i = 0x0000000000000000), do_allow_print=(i = 0x0000000000000038)) at lread.c:2613:3
    frame #105: 0x0000000119e9f0f4 mule-3352613d-d3b3728f.eln`F6c6f61642d776974682d636f64652d636f6e76657273696f6e_load_with_code_conversion_0 + 788
    frame #106: 0x0000000100d37800 bootstrap-emacs`funcall_subr(subr=0x000000010a0fdaa0, numargs=4, args=0x000000016fdede78) at eval.c:3184:15
    frame #107: 0x0000000100d35ff8 bootstrap-emacs`funcall_general(fun=(i = 0x000000010a0fdaa5), numargs=4, args=0x000000016fdede78) at eval.c:3055:12
    frame #108: 0x0000000100d05508 bootstrap-emacs`Ffuncall(nargs=5, args=0x000000016fdede70) at eval.c:3108:21
    frame #109: 0x0000000100ed0bc8 bootstrap-emacs`Fload(file=(i = 0x000000010bec1eec), noerror=(i = 0x0000000007b45118), nomessage=(i = 0x0000000007fd26e8), nosuffix=(i = 0x0000000000000000), must_suffix=(i = 0x0000000000000000)) at lread.c:1616:10
    frame #110: 0x0000000100d37800 bootstrap-emacs`funcall_subr(subr=0x0000000101f11700, numargs=3, args=0x000000011ad04838) at eval.c:3184:15
    frame #111: 0x0000000100f9a464 bootstrap-emacs`exec_byte_code(fun=(i = 0x000000010bea500d), args_template=0, nargs=0, args=0x000000011ad04830) at bytecode.c:828:14
    frame #112: 0x0000000100d39044 bootstrap-emacs`funcall_lambda(fun=(i = 0x000000010bea513d), nargs=0, arg_vector=0x000000016fdf7e28) at eval.c:3267:9
    frame #113: 0x0000000100d36164 bootstrap-emacs`funcall_general(fun=(i = 0x000000010bea513d), numargs=0, args=0x000000016fdf7e28) at eval.c:3059:12
    frame #114: 0x0000000100d05508 bootstrap-emacs`Ffuncall(nargs=1, args=0x000000016fdf7e20) at eval.c:3108:21
    frame #115: 0x000000011a19e6a8 startup-bbc6ea72-6643f97a.eln`F737461727475702d2d6c6f61642d757365722d696e69742d66696c65_startup__load_user_init_file_0 + 768
    frame #116: 0x0000000100d37428 bootstrap-emacs`funcall_subr(subr=0x000000010a105b10, numargs=3, args=0x000000016fdf9258) at eval.c:3180:15
    frame #117: 0x0000000100d35ff8 bootstrap-emacs`funcall_general(fun=(i = 0x000000010a105b15), numargs=3, args=0x000000016fdf9258) at eval.c:3055:12
    frame #118: 0x0000000100d05508 bootstrap-emacs`Ffuncall(nargs=4, args=0x000000016fdf9250) at eval.c:3108:21
    frame #119: 0x000000011a19fdb8 startup-bbc6ea72-6643f97a.eln`F636f6d6d616e642d6c696e65_command_line_0 + 4688
    frame #120: 0x0000000100d370bc bootstrap-emacs`funcall_subr(subr=0x000000010a108160, numargs=0, args=0x000000016fdfa640) at eval.c:3174:15
    frame #121: 0x0000000100d35ff8 bootstrap-emacs`funcall_general(fun=(i = 0x000000010a108165), numargs=0, args=0x000000016fdfa640) at eval.c:3055:12
    frame #122: 0x0000000100d05508 bootstrap-emacs`Ffuncall(nargs=1, args=0x000000016fdfa638) at eval.c:3108:21
    frame #123: 0x000000011a19cb2c startup-bbc6ea72-6643f97a.eln`F6e6f726d616c2d746f702d6c6576656c_normal_top_level_0 + 3684
    frame #124: 0x0000000100cfa590 bootstrap-emacs`eval_sub(form=(i = 0x000000010a0fb47b)) at eval.c:2610:15
    frame #125: 0x0000000100d2d894 bootstrap-emacs`Feval(form=(i = 0x000000010a0fb47b), lexical=(i = 0x0000000000000038)) at eval.c:2472:28
    frame #126: 0x000000010083dab0 bootstrap-emacs`top_level_2 at keyboard.c:1190:21
    frame #127: 0x0000000100d1e96c bootstrap-emacs`internal_condition_case(bfun=(bootstrap-emacs`top_level_2 at keyboard.c:1182), handlers=(i = 0x00000000000000a8), hfun=(bootstrap-emacs`cmd_error at keyboard.c:976)) at eval.c:1627:25
    frame #128: 0x000000010083d3cc bootstrap-emacs`top_level_1(ignore=(i = 0x0000000000000000)) at keyboard.c:1202:5
    frame #129: 0x0000000100d18bfc bootstrap-emacs`internal_catch(tag=(i = 0x0000000000014040), func=(bootstrap-emacs`top_level_1 at keyboard.c:1199), arg=(i = 0x0000000000000000)) at eval.c:1306:25
    frame #130: 0x00000001007a99d4 bootstrap-emacs`command_loop at keyboard.c:1151:2
    frame #131: 0x00000001007a8b04 bootstrap-emacs`recursive_edit_1 at keyboard.c:760:9
    frame #132: 0x00000001007ab100 bootstrap-emacs`Frecursive_edit at keyboard.c:843:3
    frame #133: 0x00000001007993a0 bootstrap-emacs`main(argc=1, argv=0x000000016fdff280) at emacs.c:2658:3
    frame #134: 0x000000018ddec274 dyld`start + 2840
  thread #2
    frame #0: 0x000000018e12af54 libsystem_kernel.dylib`mach_msg2_trap + 8
    frame #1: 0x000000018e13d604 libsystem_kernel.dylib`mach_msg2_internal + 80
    frame #2: 0x000000018e133af8 libsystem_kernel.dylib`mach_msg_overwrite + 480
    frame #3: 0x000000018e12b29c libsystem_kernel.dylib`mach_msg + 24
    frame #4: 0x00000001015e23bc bootstrap-emacs`protCatchThread
    frame #5: 0x000000018e16c2e4 libsystem_pthread.dylib`_pthread_start + 136
  thread #5
    frame #0: 0x000000018e1311a8 libsystem_kernel.dylib`__pselect + 8
    frame #1: 0x000000018e131080 libsystem_kernel.dylib`pselect$DARWIN_EXTSN + 64
    frame #2: 0x000000010138cfb8 bootstrap-emacs`-[EmacsApp fd_handler:](self=0x0000000109901540, _cmd="fd_handler:", unused=0x0000000000000000) at nsterm.m:6441:20
    frame #3: 0x000000018f41cc24 Foundation`__NSThread__start__ + 724
    frame #4: 0x000000018e16c2e4 libsystem_pthread.dylib`_pthread_start + 136
  thread #6, name = 'com.apple.NSEventThread'
    frame #0: 0x000000018e12af54 libsystem_kernel.dylib`mach_msg2_trap + 8
    frame #1: 0x000000018e13d604 libsystem_kernel.dylib`mach_msg2_internal + 80
    frame #2: 0x000000018e133af8 libsystem_kernel.dylib`mach_msg_overwrite + 480
    frame #3: 0x000000018e12b29c libsystem_kernel.dylib`mach_msg + 24
    frame #4: 0x000000018e254a3c CoreFoundation`__CFRunLoopServiceMachPort + 160
    frame #5: 0x000000018e25329c CoreFoundation`__CFRunLoopRun + 1212
    frame #6: 0x000000018e252724 CoreFoundation`CFRunLoopRunSpecific + 588
    frame #7: 0x0000000191ee1a20 AppKit`_NSEventThread + 148
    frame #8: 0x000000018e16c2e4 libsystem_pthread.dylib`_pthread_start + 136
  thread #7
    frame #0: 0x000000018e1670e8 libsystem_pthread.dylib`start_wqthread
(lldb) 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#75482: scratch/igc: Building with ASan fails
  2025-01-12 10:53   ` Stefan Kangas
@ 2025-01-12 11:02     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2025-01-12 11:10       ` Stefan Kangas
  0 siblings, 1 reply; 9+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-01-12 11:02 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 75482, gerd

"Stefan Kangas" <stefankangas@gmail.com> writes:

> Pip Cet <pipcet@protonmail.com> writes:
>
>> "Stefan Kangas" <stefankangas@gmail.com> writes:
>>
>>> I was experimenting with building the scratch/igc branch with
>>> -fsanitize=address, and I ran into this:
>>
>> What kind of system is that on?
>
> Sorry for the late reply here.  This is macOS, compiling with
>
>     ./configure --with-mps --enable-checking="yes,igc_debug" \
>     --enable-check-lisp-object-type \
>     CFLAGS="$CFLAGS -O0 -g3 -fsanitize=address"

I assume that's with clang, right?

>>> =================================================================
>>> ==134==ERROR: AddressSanitizer: stack-buffer-underflow on address
>>> 0x00016ac1df20 at pc 0x00010617584c bp 0x00016ac1d690 sp
>>> 0x00016ac1d688
>>> READ of size 8 at 0x00016ac1df20 thread T0
>>>     #0 0x106175848 in scan_ambig igc.c:1552
>>>     #1 0x106529218 in StackScan ss.c:68
>>>     #2 0x10650e8a4 in ThreadScan thxc.c:242
>>>     #3 0x10650e46c in RootScan root.c
>>>     #4 0x10654ad88 in traceScanRootRes trace.c:528
>>>     #5 0x10650cec8 in TraceStart trace.c:1694
>>>     #6 0x106500fd8 in PolicyStartTrace policy.c:335
>>>     #7 0x106500544 in TracePoll trace.c:1840
>>>     #8 0x1064ec440 in ArenaPoll global.c:745
>>>     #9 0x1064ed30c in mps_ap_fill mpsi.c:1097
>>>     #10 0x10617d660 in alloc_impl igc.c:3954
>>
>> AFAICT, what that says is that ASAN saw scan_ambig look at a parent's
>> stack frame; that is quite common in C (passing a pointer to a stack
>> variable to another function), so I assume ASAN has heuristics for
>> determining whether the pointer has been exposed to inner functions or
>> not.
>>
>> In this case, the heuristic fails to determine that it's okay for
>> scan_ambig to look at stack frame #10.  I don't think that ASAN can be
>> fixed to recognize the peculiar case of a thread scanning its own stack
>> for conservative GC marking: if we want it to work, we need to add ASAN
>> calls in igc.c, just as we did in alloc.c.
>
> The patch I just installed simply makes ASan ignore that we are scanning
> bytes in its redzone on the stack, which seems to be all that was needed
> to get the build to work.

Excellent.  No objections whatsoever to doing that.

>> I'm not in favor of doing that; there's a lot of ASAN-related noise in
>> alloc.c, and it makes reading that file difficult.  My impression is we
>> didn't find very many bugs by adding the ASAN code.  On the other hand,
>> igc.c isn't quite as complicated and there would be fewer calls.
>
> I hope that it will be easier to get igc to work with ASan.  We'll see.

I was wrong.  Apparently, ASAN found quite a few bugs in files other
than alloc.c, so it makes perfect sense to get it to work when IGC is in
use.

>>>     #252 0x105c80f4c in FletX eval.c:1055
>>>     #253 0x105c69f28 in eval_sub eval.c:2564
>>>     #254 0x105c6e8fc in Fprogn eval.c:452
>>
>> That's not the top of the stack; I assume ASAN just gave up when it hit
>> stack frame #255.  If ASAN can't give us complete stack traces, that's
>> another good reason not to use it.
>
> I was able to get a complete backtrace if I did
>
>     export ASAN_OPTIONS=abort_on_error=1
>     lldb src/emacs-bootstrap
>
> Then I could run "bt all" as usual.  You can also use breakpoints, as
> explained here
> https://github.com/google/sanitizers/wiki/AddressSanitizerAndDebugger

That's a good workaround.

Pip






^ permalink raw reply	[flat|nested] 9+ messages in thread

* bug#75482: scratch/igc: Building with ASan fails
  2025-01-12 11:02     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-01-12 11:10       ` Stefan Kangas
  0 siblings, 0 replies; 9+ messages in thread
From: Stefan Kangas @ 2025-01-12 11:10 UTC (permalink / raw)
  To: Pip Cet; +Cc: 75482, gerd

Pip Cet <pipcet@protonmail.com> writes:

> "Stefan Kangas" <stefankangas@gmail.com> writes:
>
>>     ./configure --with-mps --enable-checking="yes,igc_debug" \
>>     --enable-check-lisp-object-type \
>>     CFLAGS="$CFLAGS -O0 -g3 -fsanitize=address"
>
> I assume that's with clang, right?

Yes.  Sorry for not being explicit about that.





^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2025-01-12 11:10 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-10 22:04 bug#75482: scratch/igc: Building with ASan fails Stefan Kangas
2025-01-11  4:22 ` Gerd Möllmann
2025-01-11  5:41   ` Gerd Möllmann
2025-01-12 10:22     ` Stefan Kangas
2025-01-11  5:20 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-01-11  5:53   ` Gerd Möllmann
2025-01-12 10:53   ` Stefan Kangas
2025-01-12 11:02     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-01-12 11:10       ` Stefan Kangas

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.