sigaltstack(2) - wariua/manpages-ko GitHub Wiki

NAME

sigaltstack - μ‹œκ·Έλ„ μŠ€νƒ λ¬Έλ§₯ μ„€μ •ν•˜κ³  μ–»κΈ°

SYNOPSIS

#include <signal.h>

int sigaltstack(const stack_t *ss, stack_t *old_ss);

glibc κΈ°λŠ₯ 확인 맀크둜 μš”κ±΄ (feature_test_macros(7) μ°Έκ³ ):

sigaltstack()
_XOPEN_SOURCE >= 500
|| /* glibc 2.12λΆ€ν„°: */ _POSIX_C_SOURCE >= 200809L
|| /* glibc 버전 <= 2.19: */ _BSD_SOURCE

DESCRIPTION

sigaltstack()을 톡해 ν”„λ‘œμ„ΈμŠ€μ—μ„œ μƒˆ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ„ μ§€μ •ν•˜κ³  κΈ°μ‘΄ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ˜ μƒνƒœλ₯Ό μ–»μ–΄ 올 수 μžˆλ‹€. μ‹œκ·Έλ„ ν•Έλ“€λŸ¬ μ„€μ •μ—μ„œ μš”μ²­ν•˜λ©΄ μ‹œκ·Έλ„ ν•Έλ“€λŸ¬ μ‹€ν–‰ λ™μ•ˆ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ„ μ‚¬μš©ν•œλ‹€.

λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒ μ‚¬μš©μ„ μœ„ν•œ 일반적인 μ ˆμ°¨λŠ” λ‹€μŒκ³Ό κ°™λ‹€.

  1. λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ— μ‚¬μš©ν•  λ©”λͺ¨λ¦¬ μ˜μ—­μ„ ν• λ‹Ήν•œλ‹€.
  2. sigaltstack()을 μ‚¬μš©ν•΄ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ˜ μ‘΄μž¬μ™€ μœ„μΉ˜λ₯Ό μ‹œμŠ€ν…œμ—κ²Œ μ•Œλ¦°λ‹€.
  3. sigaction(2)으둜 μ‹œκ·Έλ„ ν•Έλ“€λŸ¬λ₯Ό μ„€μ •ν•  λ•Œ SA_ONSTACK ν”Œλž˜κ·Έλ₯Ό μ§€μ •ν•΄μ„œ μ‹œκ·Έλ„ ν•Έλ“€λŸ¬λ₯Ό λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒ μƒμ—μ„œ μ‹€ν–‰ν•΄μ•Ό 함을 μ‹œμŠ€ν…œμ—κ²Œ μ•Œλ¦°λ‹€.

ss μΈμžλŠ” μƒˆ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ„ μ§€μ •ν•˜λŠ”λ° μ‚¬μš©ν•˜λ©° old_ss μΈμžλŠ” ν˜„μž¬ μ„€μ •λœ μ‹œκ·Έλ„ μŠ€νƒμ— λŒ€ν•œ 정보λ₯Ό μ–»λŠ” 데 μ‚¬μš©ν•œλ‹€. 이 쀑 ν•œ κ°€μ§€ μž‘μ—…λ§Œ μˆ˜ν–‰ν•˜κ³  μ‹Άλ‹€λ©΄ λ‹€λ₯Έ 인자λ₯Ό NULL둜 μ§€μ •ν•  수 μžˆλ‹€.

이 ν•¨μˆ˜ μΈμžλ“€μ˜ νƒ€μž…μΈ stack_t νƒ€μž…μ€ λ‹€μŒκ³Ό 같이 μ •μ˜λ˜μ–΄ μžˆλ‹€.

typedef struct {
    void  *ss_sp;     /* μŠ€νƒμ˜ κΈ°μ€€ μ£Όμ†Œ */
    int    ss_flags;  /* ν”Œλž˜κ·Έ */
    size_t ss_size;   /* μŠ€νƒμ˜ λ°”μ΄νŠΈ 수 */
} stack_t;

μƒˆ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ„ μ„€μ •ν•˜λ €λ©΄ 이 ꡬ쑰체의 ν•„λ“œλ₯Ό λ‹€μŒκ³Ό 같이 μ„€μ •ν•œλ‹€.

ss.ss_flags

이 ν•„λ“œλŠ” 0 λ˜λŠ” λ‹€μŒ ν”Œλž˜κ·Έλ₯Ό λ‹΄λŠ”λ‹€.

SS_AUTODISARM (λ¦¬λˆ…μŠ€ 4.7λΆ€ν„°)

μ‹œκ·Έλ„ ν•Έλ“€λŸ¬ μ§„μž… μ‹œ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒ 섀정을 λΉ„μš΄λ‹€. μ‹œκ·Έλ„ ν•Έλ“€λŸ¬κ°€ λ°˜ν™˜ν•  λ•Œ 이전 λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒ 섀정을 λ³΅μ›ν•œλ‹€.

swapcontext(3)둜 μ‹œκ·Έλ„ ν•Έλ“€λŸ¬μ—μ„œ λ‹€λ₯Έ λ¬Έλ§₯으둜 μ „ν™˜ν•˜λŠ” 것을 μ•ˆμ „ν•˜κ²Œ λ§Œλ“€κΈ° μœ„ν•΄ 이 ν”Œλž˜κ·Έκ°€ μΆ”κ°€λ˜μ—ˆλ‹€. 이 ν”Œλž˜κ·Έκ°€ μ—†μœΌλ©΄ μ΄ν›„μ˜ μ‹œκ·Έλ„ μ²˜λ¦¬κ°€ μ „ν™˜ μ „ μ‹œκ·Έλ„ ν•Έλ“€λŸ¬μ˜ μƒνƒœλ₯Ό μ˜€μ—Όμ‹œν‚€κ²Œ λœλ‹€. 이 ν”Œλž˜κ·Έλ₯Ό μ§€μ›ν•˜μ§€ μ•ŠλŠ” μ»€λ„μ—μ„œ 이 ν”Œλž˜κ·Έλ₯Ό μ£Όλ©΄ sigaltstack()이 EINVAL 였λ₯˜λ‘œ μ‹€νŒ¨ν•œλ‹€.

ss.ss_sp
이 ν•„λ“œλŠ” μŠ€νƒμ˜ μ‹œμž‘ μ£Όμ†Œλ₯Ό λ‚˜νƒ€λ‚Έλ‹€. λŒ€μ²΄ μŠ€νƒμ—μ„œ μ‹œκ·Έλ„ ν•Έλ“€λŸ¬λ₯Ό ν˜ΈμΆœν•  λ•Œ ss.ss_sp둜 받은 μ£Όμ†Œλ₯Ό 컀널이 μžλ™μœΌλ‘œ 기반 ν•˜λ“œμ›¨μ–΄ μ•„ν‚€ν…μ²˜μ— λ§žλŠ” μ£Όμ†Œ κ²½κ³„λ‘œ μ •λ ¬ν•œλ‹€.
ss.ss_size
이 ν•„λ“œλŠ” μŠ€νƒμ˜ 크기λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ˜ 크기에 λŒ€ν•œ 일반적인 μš”κ΅¬λ“€μ„ μΆ©μ‘±ν•˜λŠ” 크기가 λ˜λ„λ‘ μƒμˆ˜ SIGSTKSZκ°€ μ •μ˜λ˜μ–΄ μžˆλ‹€. 그리고 μƒμˆ˜ MINSIGSTKSZλŠ” μ‹œκ·Έλ„ ν•Έλ“€λŸ¬ 싀행에 ν•„μš”ν•œ μ΅œμ†Œ 크기λ₯Ό κ·œμ •ν•œλ‹€.

κΈ°μ‘΄ μŠ€νƒμ„ λΉ„ν• μ„±ν™” ν•˜λ €λ©΄ ss.ss_flagsλ₯Ό SS_DISABLE둜 μ§€μ •ν•˜λ©΄ λœλ‹€. 이 경우 컀널이 ss.ss_flags의 λ‹€λ₯Έ ν”Œλž˜κ·Έμ™€ ss의 λ‚˜λ¨Έμ§€ ν•„λ“œλ“€μ„ λ¬΄μ‹œν•œλ‹€.

old_ssκ°€ NULL이 μ•„λ‹ˆλ©΄ 이λ₯Ό μ΄μš©ν•΄ sigaltstack() 호좜 전에 μ μš©λ˜μ–΄ 있던 λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ— λŒ€ν•œ 정보λ₯Ό λ°˜ν™˜ν•œλ‹€. old_ss.ss_sp ν•„λ“œμ™€ old_ss.ss_size ν•„λ“œκ°€ κ·Έ μŠ€νƒμ˜ μ‹œμž‘ μ£Όμ†Œμ™€ 크기λ₯Ό λŒλ €μ€€λ‹€. old_ss.ss_flags ν•„λ“œκ°€ λ‹€μŒ κ°’λ“€ 쀑 ν•˜λ‚˜λ₯Ό λŒλ €μ€„ 수 μžˆλ‹€.

SS_ONSTACK
ν”„λ‘œμ„ΈμŠ€κ°€ ν˜„μž¬ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒ μƒμ—μ„œ μ‹€ν–‰ 쀑이닀. (참고둜 ν”„λ‘œμ„ΈμŠ€κ°€ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒ μœ„μ—μ„œ μ‹€ν–‰ 쀑이면 κ·Έ μŠ€νƒμ„ λ°”κΎΈλŠ” 것이 λΆˆκ°€λŠ₯ν•˜λ‹€.)
SS_DISABLE

λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ΄ ν˜„μž¬ λΉ„ν™œμ„±ν™”λ˜μ–΄ μžˆλ‹€.

λ˜λŠ” ν”„λ‘œμ„ΈμŠ€κ°€ ν˜„μž¬ SS_AUTODISARM ν”Œλž˜κ·Έλ‘œ μ„€μ •ν•œ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ—μ„œ μ‹€ν–‰ 쀑이어도 이 값을 λ°˜ν™˜ν•œλ‹€. 이 경우 swapcontext(3)둜 μ‹œκ·Έλ„ ν•Έλ“€λŸ¬μ—μ„œ λ‹€λ₯Έ λ¬Έλ§₯으둜 μ „ν™˜ν•˜λŠ” 것이 μ•ˆμ „ν•˜λ‹€. 또 sigaltstack()을 λ‹€μ‹œ ν˜ΈμΆœν•΄μ„œ 또 λ‹€λ₯Έ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ„ μ„€μ •ν•˜λŠ” 것도 κ°€λŠ₯ν•˜λ‹€.

SS_AUTODISARM
λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ΄ μœ„μ—μ„œ κΈ°μˆ ν•œ κ²ƒμ²˜λŸΌ μžλ™ ν•΄μ œν•˜λ„λ‘ ν‘œμ‹œλ˜μ–΄ μžˆλ‹€.

ssλ₯Ό NULL둜 μ§€μ •ν•˜κ³  old_ssλ₯Ό NULL μ•„λ‹Œ κ°’μœΌλ‘œ μ§€μ •ν•˜λ©΄ λ³€κ²½ 없이 ν˜„μž¬μ˜ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒ 섀정을 얻을 수 μžˆλ‹€.

RETURN VALUE

sigaltstack()은 성곡 μ‹œ 0을 λ°˜ν™˜ν•˜κ³  μ‹€νŒ¨ μ‹œ -1을 λ°˜ν™˜ν•˜λ©΄μ„œ 였λ₯˜λ₯Ό λ‚˜νƒ€λ‚΄λ„λ‘ errnoλ₯Ό μ„€μ •ν•œλ‹€.

ERRORS

EFAULT
ssλ‚˜ old_ssκ°€ NULL이 μ•„λ‹ˆλ©° ν”„λ‘œμ„ΈμŠ€μ˜ μ£Όμ†Œ 곡간 λ°–μ˜ μ˜μ—­μ„ 가리킀고 μžˆλ‹€.
EINVAL
ssκ°€ NULL이 μ•„λ‹ˆλ©° ss_flags ν•„λ“œκ°€ μœ νš¨ν•˜μ§€ μ•Šμ€ ν”Œλž˜κ·Έλ₯Ό λ‹΄κ³  μžˆλ‹€.
ENOMEM
μƒˆ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ— μ§€μ •ν•œ 크기 ss.ss_sizeκ°€ MINSIGSTKSZ보닀 μž‘λ‹€.
EPERM
μ‚¬μš© 쀑인 λ™μ•ˆ (즉 ν”„λ‘œμ„ΈμŠ€κ°€ 이미 ν˜„ν–‰ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒ μœ„μ—μ„œ μ‹€ν–‰ 쀑인 λ™μ•ˆ) λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒ λ³€κ²½ μ‹œλ„κ°€ μ΄λ€„μ‘Œλ‹€.

ATTRIBUTES

이 μ ˆμ—μ„œ μ‚¬μš©ν•˜λŠ” μš©μ–΄λ“€μ— λŒ€ν•œ μ„€λͺ…은 attributes(7)λ₯Ό 보라.

μΈν„°νŽ˜μ΄μŠ€ 속성 κ°’
sigaltstack() μŠ€λ ˆλ“œ μ•ˆμ „μ„± MT-Safe

CONFORMING TO

POSIX.1-2001, POSIX.1-2008, SUSv2, SVr4

SS_AUTODISARM ν”Œλž˜κ·ΈλŠ” λ¦¬λˆ…μŠ€ ν™•μž₯이닀.

NOTES

λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ„ κ°€μž₯ ν”νžˆ μ“°λŠ” 곳은 정상적인 ν”„λ‘œμ„ΈμŠ€ μŠ€νƒμ— μ‚¬μš© κ°€λŠ₯ 곡간이 고갈된 경우 λ°œμƒν•˜λŠ” SIGSEGV μ‹œκ·Έλ„μ„ λ‹€λ£° λ•Œμ΄λ‹€. ν”„λ‘œμ„ΈμŠ€ μŠ€νƒ μƒμ—μ„œ SIGSEGV에 λŒ€ν•œ μ‹œκ·Έλ„ ν•Έλ“€λŸ¬λ₯Ό ν˜ΈμΆœν•  수 μ—†λŠ” 이런 경우λ₯Ό 닀루렀면 λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ„ μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

ν”„λ‘œμ„ΈμŠ€κ°€ ν‘œμ€€ μŠ€νƒμ„ κ³ κ°ˆμ‹œν‚¬ μˆ˜λ„ μžˆλ‹€κ³  μ˜ˆμƒλœλ‹€λ©΄ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ„ μ„€μ •ν•˜λŠ” 것이 μœ μš©ν•˜λ‹€. 예λ₯Ό λ“€λ©΄ μœ„λ‘œ μžλΌλŠ” νž™κ³Ό 마주칠 μ •λ„λ‘œ μŠ€νƒμ΄ 크게 μžλΌκ±°λ‚˜ setrlimit(RLIMIT_STACK, &rlim) 호좜둜 μ„€μ •ν•œ μ œν•œμ— λ„λ‹¬ν•˜μ—¬ 그런 상황이 λ°œμƒν•  수 μžˆλ‹€. ν‘œμ€€ μŠ€νƒμ΄ 고갈되면 컀널이 ν”„λ‘œμ„ΈμŠ€μ—κ²Œ SIGSEGV μ‹œκ·Έλ„μ„ 보낸닀. 이런 μƒν™©μ—μ„œ κ·Έ μ‹œκ·Έλ„μ„ μž‘μ„ μœ μΌν•œ 방법이 λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ΄λ‹€.

λ¦¬λˆ…μŠ€κ°€ μ§€μ›ν•˜λŠ” ν•˜λ“œμ›¨μ–΄ μ•„ν‚€ν…μ²˜λ“€ λŒ€λΆ€λΆ„μ—μ„œλŠ” μŠ€νƒμ΄ μ•„λž˜λ‘œ μžλž€λ‹€. sigaltstack()μ—μ„œλŠ” μŠ€νƒ μ„±μž₯ λ°©ν–₯을 μžλ™μœΌλ‘œ κ³ λ €ν•΄ μ€€λ‹€.

λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ—μ„œ μ‹€ν–‰ 쀑인 μ‹œκ·Έλ„ ν•Έλ“€λŸ¬μ—μ„œ ν˜ΈμΆœν•˜λŠ” ν•¨μˆ˜λ“€ μ—­μ‹œ κ·Έ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ„ μ‚¬μš©ν•˜κ²Œ λœλ‹€. (ν”„λ‘œμ„ΈμŠ€κ°€ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ—μ„œ μ‹€ν–‰ 쀑인 λ™μ•ˆ λ‹€λ₯Έ μ‹œκ·Έλ„μ— λŒ€ν•œ ν•Έλ“€λŸ¬κ°€ ν˜ΈμΆœλ˜λŠ” κ²½μš°λ„ λ§ˆμ°¬κ°€μ§€μ΄λ‹€.) ν‘œμ€€ μŠ€νƒκ³Ό 달리 μ‹œμŠ€ν…œμ—μ„œ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ„ μžλ™μœΌλ‘œ λŠ˜μ—¬ μ£Όμ§€ μ•ŠλŠ”λ‹€. λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ— ν• λ‹Ήλœ 크기λ₯Ό λ„˜μ–΄μ„œλ©΄ μ˜ˆμƒ λΆˆκ°€λŠ₯ν•œ κ²°κ³Όλ₯Ό μœ λ°œν•˜κ²Œ λœλ‹€.

execve(2) 호좜 성곡 μ‹œ κΈ°μ‘΄ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ΄ 있으면 μ œκ±°ν•œλ‹€. fork(2)둜 μƒμ„±ν•œ μžμ‹ ν”„λ‘œμ„ΈμŠ€λŠ” λΆ€λͺ¨μ˜ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒ μ„€μ • 볡사본을 λ¬Όλ €λ°›λŠ”λ‹€.

sigaltstack()은 μ΄μ „μ˜ sigstack() ν˜ΈμΆœμ„ λŒ€μ‹ ν•œλ‹€. ν•˜μœ„ ν˜Έν™˜μ„±μ„ μœ„ν•΄ glibcμ—μ„œλŠ” sigstack()도 μ œκ³΅ν•œλ‹€. μƒˆλ‘œμš΄ μ‘μš©λ“€μ€ λͺ¨λ‘ sigaltstack()을 μ΄μš©ν•΄ μž‘μ„±ν•˜λŠ” 게 μ’‹λ‹€.

역사

4.2BSD에 sigstack() μ‹œμŠ€ν…œ 호좜이 μžˆμ—ˆλ‹€. 살짝 λ‹€λ₯Έ ꡬ쑰체λ₯Ό μ‚¬μš©ν–ˆλŠ”λ° ν˜ΈμΆœμžκ°€ μŠ€νƒ μ„±μž₯ λ°©ν–₯을 μ•Œκ³  μžˆμ–΄μ•Ό ν•œλ‹€λŠ” μ‹¬κ°ν•œ 단점이 μžˆμ—ˆλ‹€.

EXAMPLE

λ‹€μŒ μ½”λ“œ 쑰각은 sigaltstack()을 (그리고 sigaction(2)을) μ΄μš©ν•΄ SIGSEGV μ‹œκ·Έλ„ ν•Έλ“€λŸ¬κ°€ μ‚¬μš©ν•  λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ„ μ„€μΉ˜ν•˜λŠ” 것을 보여 μ€€λ‹€.

stack_t ss;

ss.ss_sp = malloc(SIGSTKSZ);
if (ss.ss_sp == NULL) {
    perror("malloc");
    exit(EXIT_FAILURE);
}

ss.ss_size = SIGSTKSZ;
ss.ss_flags = 0;
if (sigaltstack(&ss, NULL) == -1) {
    perror("sigaltstack");
    exit(EXIT_FAILURE);
}

sa.sa_flags = SA_ONSTACK;
sa.sa_handler = handler();      /* μ‹œκ·Έλ„ ν•Έλ“€λŸ¬ μ£Όμ†Œ */
sigemptyset(&sa.sa_mask);
if (sigaction(SIGSEGV, &sa, NULL) == -1) {
    perror("sigaction");
    exit(EXIT_FAILURE);
}

BUGS

λ¦¬λˆ…μŠ€ 2.2 μ΄μ „μ—μ„œ ss.sa_flags에 μ§€μ •ν•  수 μžˆλŠ” μœ μΌν•œ ν”Œλž˜κ·ΈλŠ” SS_DISABLEμ΄μ—ˆλ‹€. λ¦¬λˆ…μŠ€ 2.4 컀널 λ¦΄λ¦¬μŠ€κΉŒμ§€ κ³Όμ •μ—μ„œ λˆ„κ΅°κ°€ λ‚΄μš©μ„ ν˜Όλ™ν•˜μ—¬ 컀널이 ss.ss_flagsμ—μ„œ SS_ONSTACK을 받아듀이도둝 ν–ˆλ‹€. μ΄λ ‡κ²Œ ν–ˆμ„ λ•Œμ˜ λ™μž‘ 방식은 ss_flagsκ°€ 0일 λ•Œμ™€ κ°™λ‹€. λ‹€λ₯Έ κ΅¬ν˜„λ“€μ—μ„œ, 그리고 POSIX.1에 λ”°λ₯΄λ©΄ SS_ONSTACK은 old_ss.ss_flagsμ—μ„œ μ•Œλ €μ£ΌλŠ” ν”Œλž˜κ·Έλ‘œλ§Œ λ“±μž₯ν•œλ‹€. ss.ss_flagsμ—μ„œ 이 ν”Œλž˜κ·Έλ₯Ό μ§€μ •ν•  ν•„μš”κ°€ μ „ν˜€ μ—†λ‹€. (그리고 사싀 κ·Έλ ‡κ²Œ ν•˜λ©΄ 이식성이 λ–¨μ–΄μ§„λ‹€. μ–΄λ–€ κ΅¬ν˜„λ“€μ—μ„œλŠ” ss.ss_flags에 SS_ONSTACK을 μ§€μ •ν•˜λ©΄ 였λ₯˜λ₯Ό 뱉기 λ•Œλ¬Έμ΄λ‹€.)

SEE ALSO

execve(2), setrlimit(2), sigaction(2), siglongjmp(3), sigsetjmp(3), signal(7)


2017-11-08

⚠️ **GitHub.com Fallback** ⚠️