« Previous : 1 : ... 41 : 42 : 43 : 44 : 45 : 46 : 47 : 48 : 49 : ... 215 : Next »

1. 침례교

기독교의 여러 교파 중 침례교는..

  • 딱히 종교 개혁에서 유래되지 않았고, 더 옛날부터 있었다고 여겨진다. 천주교는 물론이고 일부 개신교 교파로부터도 박해를 받았다.
  • 이름이 말하는 바와 같이 세례가 아니라 침례가 성경적으로 옳다고 본다. 온몸이 물에 잠겼다가 나와야 된다.
  • 침례는 이미 구원받은 후의 신앙고백 인증일 뿐이지, 그 자체가 구원의 조건이거나 다른 의미를 지니고 있지 않다.
  • 특히 유아세례를 인정하지 않는다. 그건 할례나 안수 따위와 아무 상관 없는 관행이고, 대상과 방법이 모두 잘못됐다. 적어도 10대 정도의 나이가 됐고 스스로 선과 악을 분별하고 내 믿음을 자기 말로 고백할 능력이 돼야만 침례를 준다.

* 개인의 혼의 자유의지를 매우 존중하며 단호한 정교분리를 주장한다. 미국이 민간에서의 강한 기독교 배경에도 불구하고 독일처럼 국교가 있고 목사가 공무원인 나라가 되지 않은 것에는 침례교인들이 매우 큰 기여를 했다!
미국의 건국 모델은 후대에 세워진 세계 다른 나라들과 정부에도 선한 모범 참고 사례가 되었다.

* 침례를 받을 자격이 안 되는 너무 어린 아이, 스스로 선과 악을 분별할 능력이 없는 아기 등은 죽으면 그냥 바로 천국으로 간다. 유아세례를 받았건 말건 그것과는 전혀 무관하다! 내가 이 개념에다가 개인적으로 붙인 명칭은 ‘특례 구원’이다. 이런 애들은 죄에 대한 책임이 부과되지 않는다.
세종대왕이나 이순신은 자기 죄 가운데 죽었다면 지옥에 갈 수 있다. 하지만 낙태돼서 죽은 애들, 영 유아 때 병에 걸리거나 굶어 죽은 애들, 그리고 특별히 올해 초에 전국민에게 큰 슬픔과 분노를 안겼던 학대 피해자인 정인이 같은 애는 절대로 지옥에 가지 않는다.

사실, 천국에 가 보면 예수 믿어서 구원받은 사람보다, 저런 특례구원으로 온 사람이 인류 역사상 더 많을 거라는 게 내 추측이다.
(예수님 탄생 당시에 헤롯 왕에게 학살당한 2살 이하 동갑내기 아기들이 지옥에 가 있을 거라고는 전혀 여겨지지 않는다. 만약 그런 거라면 개독안티들이 이것 갖고 하나님의 성품에 대해 온갖 신성모독적인 조롱을 늘어놔도 실드를 칠 수 없을 것이며, 사실 나조차 기독교 안 믿었을 것이다. 아니면 믿더라도 민망해서 혼자만 조용히 믿고 말지, 이렇게 당당하게 교리를 설파하고 불신자와 논쟁할 엄두는 못 냈을 것이다.)

그 대신 이렇게 어리고, 특례 구원 실드가 있는 애들에 대해서는 부모가 반드시 의로 양육해서 특례 실드가 끝난 이후의 일생에 대한 대비를 시켜 줘야 한다. 의로 양육한다는 건 필요한 경우 체벌도 불사한다는 뜻이다. 어머니의 회초리를 무서워할 줄 알아야 나중에 지옥 형벌도 무서워할 줄 알게 된다.

난 침례의 대상과 방법에 대한 의미, 개인의 자유의지와 정교 분리, 아기의 구원 여부에 대해 침례교에서 말하는 것만치 논리적이고 합리적이고 원칙과 체계가 있는 교리를 지금까지 접하지 못했다.
난 그래서 이 교리를 믿고 지지한다. 이 정도 완성도는 되니까 주위에 복음도 전할 수 있고 기독교 관련 글을 쓰고 논쟁도 할 수 있게 됐다.

이 주제에 대해서 본인과 생각이 다른 분들은 하나님의 공의와 사랑 성품과 예정 vs 자유의지에 대해 저것보다도 논리적으로 더 잘 분간하는 교리를 믿는 것이었으면 좋겠다. 물론 킹 제임스 성경 유일주의, 삼분법(영 혼 몸 구분), 하나님 왕국과 하늘의 왕국 구분(하나님 ≠ 하느님이듯이!), 창 1:1-2 간극, 문자적인 천년왕국과 세대주의 같은 건 침례교 내부에서도 똑같이 가르치지는 않는 교리들이다.

2. 종교 개혁의 유산

옛 종교개혁자들이 후세의 크리스천들에게 남겨준 것,
혹은 원래 있었다가 모종의 이유로 봉인됐던 것을 성경을 통해 재발굴 재조명해 준 것은..

(1) 이신칭의

  • a. 마음의 회개 없는 거짓 구원, 그저 "울 교회 오세요, 그럼 님하에게 이득입니다, 예수 믿으면 복 받고 잘 삽니다" 거의 종교 영업사원 수준의 easy believism
  • b. 혹은 반대로 아예 행실의 회개와 변화가 없는 건 구원받은 것도 아님. 예수님을 단순 구원자뿐만 아니라 니 행실의 '주권자'로도 반드시 받아들여야 된다 lordship salvation

둘 다 매우 잘못된 극단이다.
내가 여러 번 강조하지만, b가 자주 저지르는 오류가 뭐냐 하면 꼭 나쁜 행실만 죄인 줄 안다는 것이다. 예수 안 믿은 거 자체부터가 엄청난 죄였고 거기서 돌이키는 게 진짜 구원을 가져다주는 회개인 걸 좀 헷갈린다.

"저는 앞으로 술 담배 끊고 모든 악한 행실을 끊고 예수님처럼 경건하게 살기로 결단했습니다. 그러니 저를 구원해 주십시오" 영접 기도를 이딴 식으로 해서는 절대로 구원 못 받는다! 절대로~!! 알겠는가?
a야 너무 수준 낮고 더 논할 가치도 없으니 제낀다.

(2) 만인 제사장

  • a. 목사님은 거~룩한 주의 종님임. 목사의 축도를 안 받으면 예배가 끝난 게 아님. 차 살 때, 가게 개업 했을 때는 영험한 목사님 초빙해서 안수 기도라도 좀 받아야 됨.
  • b. 아예 목사 직분 자체가 니골라 당의 잘못된 교리이다. 예배와 친교의 구분이 없다. 형제들이 돌아가면서 설교한다.;; (헐~)

이 역시 둘 다 잘못된 극단이다.
직분과 역할의 차이를 전부 우열 계급 투쟁으로 프레임 씌우고 체제를 전복시키는 거.. 보통 빨갱이들의 수법이다.

(3) 변개되지 않은 올바른 성경 본문 그 자체
내가 보는 성경은..

  • 헤롯 왕이 지목한 베드로 처형 시점이 유월절이 아니라 이스터라고 돼 있고(행 12:4),
  • 루시퍼와 갈보리라는 명칭이 있으며,
  • 계시록에 증인이 아니라 순교자라는 단어가 존재한다.
  • 예수 그리스도 그분의 피', '지옥' 이런 단어가 여타 성경보다 더 자주 등장한다.
  • '이사야+말라기 = 대언자들'이지.. 이거 무슨 1+1=1도 아니고, 말라기의 예언까지 이사야라고 몽땅 퉁치는 오류 역시 존재하지 않는다. (막 1:1-3)

뭐 등등..
에라스무스로부터 시작해서 루터는 바른 본문에서 독일어 성경을 번역했고, 칼빈은 제네바에서 KJV의 전신인 제네바 성경이 나올 수 있게 해 줬다.

(4) 그 밖에 루터는 너무 엄근진스럽거나 몽환적이기만 하던 교회 음악도 진입장벽을 낮추려 애썼다. "내 주는 강한 성이요"를 직접 작사 작곡하기도 했다.

Posted by 사무엘

2021/02/19 08:36 2021/02/19 08:36
, , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1856

꿈의 사람 요셉

성경에서 요셉 이야기는 창세기의 끝부분을 장식하는 매우 드라마틱한 에피소드이다. 본인은 먼 옛날에 이집트의 왕자 만화영화와 같이 모세 얘기는 한 적이 있었는데.. 모세 만만찮게 흥미진진한 요셉에 대한 이야기는 지금까지 블로그에다 진지하게 늘어놓은 적이 전혀 없었던 것을 의아하게 생각한다.;;

성경에는 예수님의 예표 인물이 여럿 있다. 하나님 앞에서 개기다가 고래에게 잡아먹히고 죽다 살아 나온 선지자(대언자) 요나조차도 예수님의 위대한 예표이다. 그런데 요셉은 예수님과 무려 100~150가지가 닮았다고.. 무슨 피타고라스 정리의 증명법만큼이나 많은 유사성이 존재한다고 여겨진다.

옛날에 한국 컨티넨탈 싱어즈에서 "꿈의 사람 요셉"이라는 뮤지컬 음반을 내놓은 적이 있고, 드림웍스에서도 이집트의 왕자 다음으로 2000년에 요셉 이야기를 애니로 만들었다. 우리나라는 스토리상 속편이 전혀 아닌 작품도 그냥 2라고 붙이는 걸 좋아해서.. 옹박 2, 이집트의 왕자 2 이런 식의 작명을 거쳐서 개봉했었다.

사용자 삽입 이미지
사용자 삽입 이미지

요셉은 세상 물정 모르는 색동옷 차림의 늦둥이 막내아들 철부지 꿈쟁이였다. 그러나 형들로부터 시기를 받아 인신매매를 당하고 하루아침에 밑바닥 노예로 전락해서 인실X을 혹독하게 체험하게 됐다..;;

그 뒤 이집트에서 겨우 기반을 잡는가 했는데 이번엔 성폭행 흉악범 누명을 쓰고 감방에 갇히고 말았다. 석방되는 동료 죄수의 꿈을 해몽해 줬지만, 그 동료의 무관심으로 인해 2년을 감방에서 더 썩었다. 요즘 현대인들의 정신 상태였다면 꿈도 희망도 없는 현실에 억울하고 원통해서 몇 번이고 자살했을 법도 한 상황이었다.

요셉은 성경에 인생 흑역사나 결점이 기록된 게 전혀에 가깝게 없으며, 특히 이성의 유혹을 성경 전체를 통틀어서 FM대로 제일 모범적으로 잘 대처한 사람이었다. 그런데 그 대가로 당장 돌아온 게 저 지경이었다. 얼마나 억울했겠는가?

성경에 자세히 적혀 있지는 않지만... 보디발의 아내 겁탈 누명의 경우, 보디발도 이건 요셉의 잘못이 아니라는 걸 알았지 싶다. 요셉이 아니라 자기 마눌에게 바람기가 있다는 것을 어느 정도 인지했을 것이다.
일개 노예가 감히 주인의 아내를 범한 건 최악의 파렴치 중범죄이며, 이건 투옥이 아니라 그냥 즉결 사형감이다. 만약 요셉이 진짜 범인이라면 그 역시 죽음을 면치 못했을 것이다.

하지만 반대로 요셉을 완전히 무죄방면해 버리면 자기들의 입장이 심히 난처해진다.
이럴 수도 저럴 수도 없으니, 절충안으로 요셉을 죽이지는 않고 그냥 감옥에 격리시키는 것으로 일을 덮은 게 아닐까? 요셉이 투옥된 뒤 보디발 집안에서는 대판 부부싸움이 벌어졌지 싶다.

이런 우여곡절을 겪은 뒤, 요셉은 "해석이란 건 {주}께 속해 있지 않습니까?"라는 명대사와 함께 파라오가 꾼 뒤숭숭한 꿈을 정확하게 해석해 냈다. 덕분에 그는 이집트에서 의전 서열이 파라오의 바로 다음 2위인 총리로 순식간에 신분이 바뀌었다.

그리고 꿈에서 계시되었던 바와 같이, 7년 풍년 이후에는 세계적으로 엄청난 흉년 기근이 창궐했다. 이에 대한 대비가 철저히 된 나라는 이집트밖에 없었다. 그러니 요셉의 형들도 곡식을 사러 이집트까지 찾아와서 요셉을 대면하게 됐다. 자, 그럼 요셉은 형들을 어떻게 대하면 좋을까?

이건 요셉이 지혜를 발휘해서 거의 하나님 급으로 공의와 사랑을 적절히 보이며 처신해야 하는 순간이었다.
마냥 "오 어째 이런 우연이~! 형님들 잘 오셨습니다~ 난 이집트 총리가 됐답니다~ 멋있쪙?" 할 수도 없고, "오냐, 옛날에 날 노예로 팔아넘겼던 네놈들이 제 발로 찾아왔군. 이제 내가 보복할 차례다. 한번 제대로 엿먹어 봐라" 이럴 수도 없었기 때문이다.

요셉은 처음에는 까칠하게 굴면서 형들이 자기 정체와 과거의 죄를 제 발로 털어놓게 만들었다. 하지만 당장 생존은 가능하게 기본적인 곡식을 무료로 챙겨 주긴 했다. (받았던 곡식값을 자루에다 같이 반환함)
형들이 과거의 죄를 완전히 회개했고, 막내동생 베냐민을 위해서는 필살의 형제애를 발휘하여 차라리 자기들이 대신 노예로 잡혀 있겠다고 호소하는 걸 확인하고서야 요셉도 드디어 엄격 진지 근엄 모드를 풀고 자기 정체를 밝혔다.

성경에서 요셉은 울었다는 장면이 유난히 자주 기록돼 있다.
어린 시절에 형들이 갑자기 자기를 매정하게 생까면서 노예상에게 팔아넘길 때, 억만 리 타지에 끌려가서 노예 취급 받을 때도 당연히 멘붕 해서 "아빠~ 보고 싶어어헝헝" 식으로 엄청나게 울었을 것이다. 하지만 성경엔 그런 건 적혀 있지 않고 더 고차원적인 이유로 운 장면만 기록됐다.

특히 저렇게 형들에게 커밍아웃 하기 직전엔 요셉은 더는 참을 수 없어서 "모두 물러가라"부터 시전했다. 그 뒤엔 궁궐 전체가 쩌렁쩌렁 울릴 정도로 "으허허허헝엉엉~!" 하며 울었다. 우리나라에서도 옛날에 방영했던 "이산가족을 찾습니다" 같은 분위기를 생각하면 된다.

나중에 부친인 야곱이 죽고 장례까지 치르자, 형들은 "이제 아버지가 돌아가시고 안 계시니 요셉이 드디어 본심을 드러내고 우리를 해코지 하면 어떡하지?" 이런 심정으로 요셉에게 자비를 호소하는 애원 간청을 했다. 성경에 따르면 요셉은 이때 마지막으로 또 울었다. 형들이 아직도 믿음이 부족하고 자기 진심을 몰라 준다고.. 이건 요 11에 기록된 예수님의 울음 장면과 매우 비슷한 분위기라고 보면 되겠다.

이것이 성경의 스토리이다. 흥미진진하지 않은가?
요셉이 형들과 이렇게 밀고 당기는 동안, 형뿐만 아니라 아버지 야곱의 믿음도 시험대에 올라서 야곱 모드와 이스라엘 모드를 오락가락했다. 야곱 모드일 때는 멘붕 자포자기 해서 "아이고~ 오래 살아 봤자 험한 꼴밖에 안 보고.. 난 어서 뒈져야지ㅠㅠㅠ" 내지 "요셉으로도 모자라서 베냐민까지? 절대 못 보내~" 같은 육신적이고 꼰대스러운 고집을 시전했었다.

요셉의 일생과 직접적인 관련은 없지만 유다와 며느리 다말 개족보 이야기(38장), 그리고 하몰-세겜 지역 보복 학살극(34장) 사건도 삽입장으로 들어가서 철도 노선으로 치면 간선에서 짧게 뻗어 나간 지선 역할을 한다. ㅎㅎ

Posted by 사무엘

2021/02/16 19:34 2021/02/16 19:34
, , , , , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1855

0. 들어가는 말

한글과 한자 문제는 정말 낡고 케케묵었고, 이미 대세를 거스를 수 없는 결론까지 도출된 주제이다. 본인 역시 나이 40이 임박한 지금까지 20여 년째 동일한 지론을 유지하고 있다. 오늘은 오랜만에 이에 대한 생각을 또 복습해 보고자 한다.

"한글로만 쓰니까 무슨 단어 뜻이 분간이 안 되고 어쩌구저쩌구" 하는 불평들은 나도 하라면 한 트럭을 끄집어낼 수 있다.
"역전의 용사"는 지고 있던 전투를 운동 경기마냥 역전(?)시킨 용사가 아니라는 것,
정부 조직을 가리킬 때의 部와, 삼권 분립을 가리킬 때의 府가 다르다는 것 뭐 등등..
온갖 병신같은 교인이나 목사나 교회 욕하면서 나는 이래서 예수 안 믿는다, 교회 안 다닌다.. 이러는 것과 완전히 똑같은 원리로 늘어놓을 수 있다.

그러나 그러나~~~~ 한글· 한자 문제에서는 다음과 같은 사항을 추가로 고려해야 한다.

1. 쓰기: 문자는 그림보다 아라비아 숫자에 더 가까워야

"한글로만 쓰니까 무슨 단어 뜻이 분간이 안 되고 어쩌구저쩌구" 하는 불평은..
그 자체조차도 나머지 90%에 달하는 이미 잘 분간되는 어휘들을 한글로 정말 편하고 빠르게 잘 읽고 쓰고 있기 때문에 나올 수 있는 불평이다! 알겠는가?

할배가 민주주의를 유린한(? 한 5%쯤?) 독재자라고..??
그 독재를 비판할 수 있는 90~95% 민주주의 토대를 닦아 놓은 사람도 할배다. 그와 같은 이치이다. 자, 이 비유를 들면 좀 이해가 빨리 되려나?

한글이나 알파벳 영단어는 최소한의 문자 체계만 떼고 나면, 최소한 모르는 단어를 사전에서 찾아 보는 거 하나는 아주 수월 간결하게 할 수 있다. 어떤 단어로부터 기본형을 유추하는 게 그리 어렵지 않으며, 유한한 요소만으로 무한의 개념을 표현한다는 체계가 있기 때문이다. 이게 문자와 그림의 본질적인 차이이기도 하다.

허나, 한자는 그림 티를 좀 못 벗은 무한집합-_- 문자이다. 모르는 글자를 옥편에서 찾는 데 시간이 얼마나 걸리며(부수, 획수..) 실패율도 얼마나 높을까?

게다가 읽을 줄 아는 것과 쓸 줄 아는 건.. 또 별개의 문제다. 컴퓨터조차 없던 시절에 "아 배고프다, 밥먹고 싶다" 이런 문장까지 백지 상태에서 한중일 어느 언어 방식이건 한자만으로 써야 한다면..?? 아 정말 끔찍하다.
설령 컴퓨터가 있다 해도 맨손에 펜만 있을 때보다야 쓰기가 편리해질 뿐이다. 다른 간편한 소리글자들도 동일하게 컴퓨터의 혜택을 받고 있다면, 한자는 이것들에 비해 입력하고 취급하기가 번거로우며 여전히 격차가 벌어진다.

2. 말하기/듣기: 글자가 아니라 알아들을 수 있는 말이 먼저

그리고 더 결정적으로, 언어라는 건 말이 먼저지 글이 먼저가 아니다. 한자의 음은 기본적으로 왕창 옛날 중국어 음의 낡은 껍데기일 뿐이다. 한글로만 써 놓으니 분간이 안 되는 문제에 앞서, 말이 글자 그림을 봐야만 이해되는 지경으로 배배 꼬이는 것이 더 문제라는 것이 나의 굳건한 지론이다.

정말 단순하고 상식적인 것에서부터 먼저 의문을 품고 제기해 보자.
수수(授受)와 매매(賣買).
세상에, 지구상의 어느 미친 언어가 '주다'와 '받다'라는 정반대 뜻을 같은 소리로 표현하냐?
'팔다'와 '사다'도 마찬가지.
'방화'는 너무 유명한 예일 테고, 그리고 명왕성의 명(冥)은 '어두울 명'이다. '밝을 명'(明)만 있는 줄 알았지? ㄲㄲㄲㄲㄲㄲ

이건 한자로 적지 않으면 뜻을 알 수 없네 타령을 하기에 앞서 말이 이상한 것이다.
형성자라는 건 알고 보면 굉장히 골때리는 제자 원리이다. 이건 글자를 생성하는 거지, 말을 생성하는 게 아니다.
(저 형성도 formation 形成이 아니라 形聲인 것쯤은 이과 출신인 나도 알고 있음)
이미 만들어지고 익숙해져 버린 명칭들은 어쩔 수 없지만, 최소한 더는 이런 식으로 조어를 하지 말고 청각 변별이 되고 잘 와닿는 쪽으로 말을 만들 생각, 시늉이라도 해야 한다.

중국어에는 성조라는 게 있어서 한국어보다는 한자 변별이 되는 편이다. 중세 땐 우리나라(조선??)조차 한자를 좀더 중국식으로 발음하려고 성조를 도입했던 것 같으나, 지금은 몽땅 사라졌다.
그런데 이 성조라는 게 노래를 부를 때는 전혀 표현될 수 없다. 한자의 발음들은 전부 문맥만으로 분별돼야 하며 의미가 잘못 전달될 수도 있다. 그렇기 때문에 내가 알기로 중국은 자기네 가요 뮤직비디오에 자막을 반드시 넣어 줘야 된다.

일본은..? 한자를 청각적으로 최대한 변별하려다 보니 읽는 방식이 너무 다양하고 복잡해져서 한자 위에 히라가나 토가 널리 쓰인다. 특히 이름 같은 생소한 고유명사의 한자는 이렇게 안 해 주면 거의 못 읽는다.
나는 이런 게 정상적인, 자연스러운 문자 생활이 "아니라고" 생각한다. 한 20년쯤 전부터 했던 생각이고 지금도 변함없다.

3. 결론: 국어 교육의 문제와 한글 전용의 문제를 서로 헷갈리지 말자

(1) 문자의 본질: 문자라는 건 말을 받아적는 도구 이상도 이하도 아니며, 그림보다는 추상적인 '숫자'에 더 가까운 면모를 지니는 게 바람직하다.
한자가 일단 익숙해지고 나면 함축적이고 시각성이 뛰어난 구석이 있는 것은 사실이다. 그러나 '읽기'의 장점을 위해서 치르는 '말하기/듣기'와 '쓰기'의 대가, 단점을 결코 만만하게 봐서는 안 된다!

(2) 한국어의 실정: 한국어는 중국어· 일본어와 달리 장단이고 성조고 훈독이고 뭐고 없다시피하며, 한자들을 정말 단순무식하게 한글 1음절로만 연결시켜 놓았다. 거기에다 한글이라는 문자도 자체적인 구조가 꽤 탄탄하며, 히라가나 카타카나 같은 한자 혼용을 전제로 한 보조용 문자가 아니다.
그러니 동음이의어 정리만 좀 해 주면 한글 전용을 하기에 매우 유리한 면모를 갖췄으며, 오늘날 실제로 그렇게 됐다.

(3) 문자 정책: 한글 전용을 전제로 하고, 마치 생소한 신조어를 드러내기 위해서 영어에서 하이픈이나 일부 음절 대문자화를 하듯이 가끔 괄호 안에 한자 병용만 하는 것으로 족하다.
개인적으로 일본식 한자어를 반대하는 소신은 아니다. 하지만 표기까지 몽땅 한자를 밝혀야 할 정도로 중구난방으로 쓰는 것은 반대다. 민족 감정 때문이 아니라 언어학적, 실용적인 측면에서만 접근한다.

(4) 교육: 뭐든지 도둑질만 아니면 많이 공부하고 배워서 나쁠 건 없고 그건 한자도 예외가 아니다. 그러나 겨우 말을 담는 껍데기 그릇을 공부하는 것 하나가 이렇게 어렵고 사용하기가 불편하고 시간이 많이 걸리는 것은 큰 문제이다. 한자는 한자어의 어원을 변별하고 의미를 정확하게 학습하는 용도로 쓰기가 아닌 '읽기' 위주로만 가르치면 된다.
국어 교육 문제를 한글 전용 문제로 돌릴 필요는 없다. 국어 교육을 똑바로 안 시키고 표기만 한자 병용을 하면? 한글 대신 헷갈려서 잘못 쓰인 한자들만 글에 가득해질 것이다.

그리고 덧붙이자면.. 한글 전용을 지지하는 사람일수록 한글 맞춤법과 띄어쓰기를 더욱 잘 지켜서 글을 써야 한다. 그게 한글의 표의성과 시각성을 살려 주는 규칙이기 때문이다.

4. 여담

(1) 성경조차 히브리건 그리스건 알파벳이건 소리만 받아적는 간결한 소리글자로 기록됐지, 뜻글자가 쓰이지 않았다.
또한, 세상에서 제일 높은 최고존엄에 대해 다루고 있는 텍스트이지만 한국어 같은 복잡한 높임법 따위 존재하지 않고 하나님도 you라고 바로 가리키는 언어로 기록됐다. 예수냐 예수님이냐 이런 게 본질적인 문제가 아니리는 것이다.

(2) 우리나라의 경우는 과거에 일제가 총칼로 한국어 한글을 말살하면서 일본어를 강요했으니 그건 극심한 저항과 반발에 부딪혔다.
그런데 그렇지 않고, 영국 미국 같은 나라가 한국을 식민지로 삼고,

  • 한국어 대신 영어를 쓰면.. X나 골치아픈 호칭, 높임법 신경쓸 필요 없이 누구나 이름으로 부르고 you로 바로 가리킬 수 있어요~!!
  • 어려운 한자로부터 해방될 수 있어요~!
  • 세계의 석학들, 최신 지식 정보와 바로 소통할 수 있어요~!
  • 미개한 붓이 아니라 타자기로 아주 빠르고 편하게 글을 쓸 수도 있어요~!

이렇게 당근만 흔들면서 접근했으면.. 당시 지식인들이 어떻게 반응했을지, 한국어와 한글의 운명이 어찌 됐을지 나는 장담을 못 하겠다. 이런 여건에서도 공 병우 같은 천재가 한글 타자기를 발명할 수 있었을까?
물론 저런 실용주의적인 사고방식 자체가 전후에 20세기 말이 돼서야 슬슬 등장했으니 이건 가정이 현실적이지 않은 뇌피셜일 뿐이다.

Posted by 사무엘

2021/02/14 08:37 2021/02/14 08:37
, , , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1854

C/C++은 성능을 위해 컴파일러나 언어 런타임이 프로그래머의 편의를 위해 뭔가를 몰래 해 주는 것을 극도로 최소화한 언어이다. 꾸밈 없고 정제되지 않은 '날것 상태 raw state'에다가 고급 프로그래밍 언어의 패러다임과 문법만을 얹은 걸 추구하다 보니, '초기화되지 않은 쓰레기값'이라는 게 존재하는 거의 유일한 언어이기도 하다.

같은 프로그램이라도 이제 막 선언된 변수나 할당된 메모리 안에 무슨 값이 들어있을지는 컴퓨터 운영체제의 상태에 따라서 그때 그때 달라진다. 반드시 0일 거라는 보장은 전혀 없다. 오히려 0 초기화는 별도의 CPU 부담이 필요한 인위적인 작업이다. global/static에 속하는 메모리만이 무조건적인 0 초기화가 보장된다.

그렇다고 쓰레기값이라는 게 완벽하게 예측 불가이면서 통계적인 질서를 갖춘 난수인 것도 물론 아니다.
그리고 Visual C++에서 프로그램을 debug 세팅으로 빌드하면 쓰레기값이라는 게 크게 달라진다. C++ 개발자라면 이 사실을 이미 경험적으로 충분히 알고 있을 것이다.

1. 갓 할당된 메모리의 기본 쓰레기값: 0xCC(스택)와 0xCD(힙)

가장 먼저, 스택에 저장되는 지역변수들은 자신을 구성하는 바이트들이 0xCC로 초기화된다. 다시 말해 디버그 빌드에서는 int x,y라고만 쓴 변수는 int x=0xCCCCCCCC, y=0xCCCCCCCC와 얼추 같게 처리된다는 것이다. 디스어셈블리를 보면 의도적으로 0xCC를 대입하는 인스트럭션이 삽입돼 들어간다.

0은 너무 인위적이고 유의미하고 깔끔한(?) 값 그 자체이고, 그 근처에 있는 1, 2나 0xFF도 자주 쓰이는 편이다. 그에 비해 0xCC는 형태가 단순하면서도 현실에서 일부러 쓰일 확률이 매우 낮은 값이다. 그렇기 때문에 여기는 초기화되지 않은 쓰레기 영역이라는 것을 시각적으로 곧장 드러내 준다.

int a[10], x; a[x]=100; 같은 문장도 x가 0으로 깔끔하게 자동 초기화됐다면 그냥 넘어가지만, 기괴한 쓰레기값이라면 곧장 에러를 발생시킬 것이다.
또한, 복잡한 클래스의 생성자에서 값이 대입되어 초기화된 멤버와 그렇지 않은 멤버가 뒤섞여 있을 때, 0xCC 같은 magic number는 탁월한 변별력을 발휘한다.

타겟이 align을 꼼꼼하게 따지는 아키텍처라면, 쓰레기값을 0x99나 0xDD 같은 홀수로 지정하는 것만으로도 초기화되지 않은 포인터 실수를 잡아낼 수 있다. 32비트에서 포인터값의 최상위 비트가 커널/사용자 영역을 분간한다면, 최하위 비트는 align 단위를 분간할 테니 말이다. 뭐 0xCC는 짝수이다만..

0xCC라는 바이트는 x86 플랫폼에서는 int 3, 즉 breakpoint를 걸어서 디버기의 실행을 중단시키는 명령을 나타내기도 한다. 그래서 이 값은 실행 파일의 기계어 코드에서 align을 맞추기 위해 공간만 차지하는 잉여 padding 용도로 위해 듬성듬성 들어가기도 한다.
Visual C++ 6 시절엔 거기에 말 그대로 아무 일도 안 하는 nop를 나타내는 0x90이 쓰였지만 2000년대부터는 디버깅의 관점에서 좀 더 유의미한 작용을 하는 0xCC로 바뀐 듯하다. 정상적인 상황이라면 컴퓨터가 이 구역의 명령을 실행할 일이 없어야 할 테니까..

다만, 힙도 아니고 스택 지역변수의 내용이 데이터가 아닌 코드로 인식되어 실행될 일이란 현실에서 전혀에 가깝게 없을 테니, 0xCC는 딱히 x86 기계어 코드를 의식해서 정해진 값은 아닐 것으로 보인다.

Visual C++의 경우, 스택 말고 malloc이나 new로 할당하는 힙(동적) 메모리는 디버그 버전에서는 내용 전체를 0xCD로 채워서 준다. 0xCC보다 딱 1 더 크다. 아하~! 이 값도 평소에 디버그 하면서 많이 보신 적이 있을 것이다.
힙의 관리는 컴파일러 내장이 아니라 CRT 라이브러리의 관할로 넘어기도 하니, 0xCD라는 값은 라이브러리의 소스인 dbgheap.c에서도 _bCleanLandFill이라는 상수명으로 확인할 수 있다.

2. 초기화되지 않은 스택 메모리의 사용 감지

C/C++ 언어는 지역변수의 값 초기화를 필수가 아닌 선택으로 남겨 놓았다. 그러니 해당 언어의 컴파일러 및 개발툴에서는 프로그래머가 초기화되지 않은 변수값을 사용하는 것을 방지하기 위해, 디버그용 빌드 한정으로라도 여러 안전장치들을 마련해 놓았다.
그걸 방지하지 않고 '방치'하면 같은 프로그램의 실행 결과가 debug/release별로 달라지는 것을 포함해 온갖 골치아픈 문제들이 발생해서 프로그래머를 괴롭히게 되기 때문이다.

int x; printf("%d", x);

이런 무식한 짓을 대놓고 하면 30년 전의 도스용 Turbo C에서도 컴파일러가 경고를 띄워 줬다. Visual C++의 에러 코드는 C4700. 그랬는데 한 Visual C++ 2010쯤부터는 이게 경고가 아니라 에러로 바뀌었다.
그리고 그 뿐만이 아니다.

int x;
if( some_condition_met(...)) x=0;
printf("%d", x);

이렇게 문장을 약간만 꼬아 놓으면 초기화를 전혀 안 하는 건 아니기 때문에 컴파일 과정에서의 C4700을 회피할 수 있다. 하지만 보다시피 if문의 조건이 충족되지 않으면 x가 여전히 초기화되지 않은 채 쓰일 수 있다. 이건 정적 분석 정도는 돌려야 감지 가능하다.
(그런데, 글쎄.. 함수의 리턴이 저런 식으로 조건부로 불완전하게 돼 있으면 컴파일만으로도 C4715 not all control paths return value 경고가 뜰 텐데.. 비초기화 변수 접근 체크는 그 정도로 꼼꼼하지 않은가 보다.)

Visual C++은 /RTC라고 디버그용 빌드에다가 run-time check라는 간단한 검사 기능을 추가하는 옵션을 제공한다. 함수 실행이 끝날 때 스택 프레임 주변을 점검해서 버퍼 오버런을 감지하는 /RTCs, 그리고 지역변수를 초기화하지 않고 사용한 것을 감지하는 /RTCu.

사용자 삽입 이미지

저 코드를 Visual C++에서 디버그 모드로 빌드해서 실행해서 if문이 충족되지 않으면 run-time check failure가 발생해서 프로그램이 정지한다. 다만, 이 메모리는 초기화만 되지 않았을 뿐 접근에 법적으로 아무 문제가 없는 스택 메모리이다. 할당되지 않은 메모리에 접근해서 access violation이 난 게 아니다. 심각한 시스템/물리적인 오류가 아니라 그저 의미· 논리적인 오류이며, 쓰기를 먼저 하지 않은 메모리에다가 읽기를 시도한 게 문제일 뿐이다.

그러니 이 버그는 해당 메모리 자체에다가 시스템 차원의 특수한 표식을 해서 잡아낸 게 아니며, 논리적으로 매우 허술하다. (0xCC이기만 하면 무조건 스톱.. 이럴 수도 없는 노릇이고!)
문제의 코드에 대한 디스어셈블리를 보면 if문이 만족되지 않으면 printf으로 가지 않고 그냥 곧장 RTC failure 핸들러를 실행하게 돼 있다.

void do_nothing(int& x) {}

int x; do_nothing(x); printf("%d", x);

그렇기 때문에 요렇게만 해 줘도 RTC를 회피하고 x의 쓰레기값을 얻는 게 가능하다. 글쎄, 정교한 정적 분석은 이것도 지적해 줄 수 있겠지만, 포인터가 등장하는 순간부터 메모리 난이도와 복잡도는 그냥 하늘로 치솟는다고 봐야 할 것이다.

하물며 처음부터 포인터로만 접근하는 힙 메모리는 RTC고 뭐고 아무 안전 장치가 없다. int *p에다가 new건 malloc이건 값이 하나 들어간 것만으로도 초기화가 된 것이거늘, 그 주소가 가리키는 p[0], p[1] 따위에 쓰레기값(0xCD)이 있건 0이 있건 알 게 무엇이겠는가????

나도 지금까지 혼동하고 있었는데, 이런 run-time check failure는 run-time error와는 다른 개념이다. 순수 가상 함수 호출 같은 건 C/C++에 존재하는 얼마 안 되는 run-time error의 일종이고 release 빌드에도 포함돼 들어간다. 하지만 RTC는 debug 빌드 전용 검사이다.

그러니 버퍼 오버런을 감지하는 보안 옵션이 /RTC만으로는 충분하지 않고 /GS가 따로 있는 것이지 싶다. /GS는 release 빌드에도 포함돼 있으며, 마소에서는 보안을 위해 모든 프로그램들이 이 옵션을 사용하여 빌드할 것을 권하고 있다.

3. 해제된 힙 메모리: 0xDD(CRT)와 0xFEEE(???)

일반적인 프로그래머라면 동적으로 할당받은 힙 메모리를 free로 해제했을 때, 거기를 가리키는 메모리 영역이 실제로 어떻게 바뀌는지에 대해 생각을 별로 하지 않는다. 사실, 할 필요가 없는 게 정상이기도 하다.
우리 프로그램은 free를 해 준 주소는 신속하게 영원히 잊어버리고, 그 주소를 보관하던 포인터는 NULL로 바꿔 버리기만 하면 된다. free 해 버린 주소를 또 엿보다가는 곧바로 메모리 에러라는 천벌을 받게 될 것이다.

그런데 실제로는, 특히 디버그 모드로 빌드 후 프로그램을 디버깅 중일 때는 free를 한 뒤에도 해당 메모리 주소가 가리키는 값을 여전히 들여다볼 수 있다. 들여다볼 수 있다는 말은 *ptr을 했을 때 access violation이 발생하지 않고 값이 나온다는 것을 의미한다.
이 공간은 나중에 새로운 메모리 할당을 위해 재사용될 수야 있다. 하지만 사용자가 디버깅의 편의를 위해 원한다면 옵션을 바꿔서 재사용되지 않게 할 수도 있다. (_CrtSetDbgFlag(_CRTDBG_DELAY_FREE_MEM_DF) 호출)

뭐, 메모리를 당장 해제하지 않는다고 해서 free 하기 전의 메모리의 원래 값까지 그대로 남아 있지는 않는다. Visual C++의 디버그용 free/delete 함수는 그 메모리 블록의 값을 일부러 0xDD (_bDeadLandFill)로 몽땅 채워 넣는다. 여기는 할당되었다가 해제된 영역임을 이런 식으로 알린다는 것이다.

실제로, free된 메모리가 곧장 흔적도 없이 사라져서 애초에 존재하지도 않았던 것처럼 접근 불가 ?? 로 표시되는 것보다는 0xDD라고 디버거의 메모리 창에 뜨는 게 dangling pointer 디버깅에 약간이나마 더 도움이 될 것이다. 이 포인터가 처음부터 그냥 쓰레기값을 가리키고 있었는지, 아니면 원래는 valid하다가 지칭 대상이 해제되어 버린 것인지를 분간할 수 있으니 말이다.

그런데 본인은 여기서 개인적으로 의문이 들었다.
본인은 지난 20여 년에 달하는 Visual C++ 프로그래밍과 메모리 문제 디버깅 경험을 떠올려 봐도.. 갓 할당된 쓰레기값인 0xCC와 0xCD에 비해, 0xDD를 본 적은 전혀 없는 건 아니지만 매우 드물었다.

dangling pointer가 가리키는 메모리의 값은 0xD?보다는 0xF?였던 적이 훨씬 더 많았다. 더 구체적으로는 2바이트 간격으로 0xFEEE (0xEE, 0xFE)이다.

사용자 삽입 이미지

인터넷 검색을 해 보니.. 이건 놀랍게도 CRT 라이브러리가 채워 넣는 값이 아니었다. free/delete가 궁극적으로 호출하는 Windows API 함수인 HeapFree가 메모리를 정리하면서 영역을 저렇게 바꿔 놓았었다. 더구나 CRT에서 0xDD로 먼저 채워 넣었던 영역을 또 덮어쓴 것이다.
이 동작에 대해서 놀라운 점은 저게 전부가 아니다.

(1) 0xFEEE 채우기는 프로그램을 Visual C++ 디버거를 붙여서(F5) 실행했을 때만 발생한다. debug 빌드라도 디버거를 붙이지 않고 그냥 Ctrl+F5로 실행하면 0xFEEE가 생기지 않는다. 그리고 release 빌드라도 디버거를 붙여서 실행하면 0xFEEE를 볼 수 있다.

(2) 더 놀라운 점은.. 내가 집과 직장 컴퓨터를 통틀어서 확인한 바로는 저 현상을 볼 수 있는 건 Visual C++ 2013 정도까지이다. 2015부터는 debug 빌드를 디버거로 붙여서 돌리더라도 0xFEEE 채움이 발생하지 않고 곧이곧대로 0xDD만 나타난다~!

운영체제가 정확하게 어떤 조건 하에서 0xFEEE를 채워 주는지 모르겠다. 인터넷 검색을 해 봐도 정확한 정보가 나오는 게 의외로 없다.
하필 Visual C++ 2015부터 저런다는 것은 CRT 라이브러리가 Universal CRT니 VCRuntime이니 하면서 구조가 크게 개편된 것과 관계가 있지 않으려나 막연히 추측만 해 볼 뿐이다.

여담이지만 HeapAlloc, GlobalAlloc, LocalAlloc은 연달아 호출했을 때 돌아오는 주소의 영역이 그리 큰 차이가 나지 않으며, 내부 동작 방식이 모두 비슷해진 것 같다. 물론 뒤의 global/local은 fixed 메모리 할당 기준으로 말이다.

4. 힙 메모리 영역 경계 표시용: 0xFD와 0xBD

0xCD, 0xDD, (0xFEEE) 말고 heap 메모리 주변에서 볼 수 있는 디버그 빌드용 magic number 바이트로는 0xFD _bNoMansLandFill와 0xBD _bAlignLandFill가 더 있다.

얘들은 사용자가 요청한 메모리.. 즉, 0xCD로 채워지는 그 메모리의 앞과 뒤에 추가로 고정된 크기만큼 채워진다. Visual C++ CRT 소스를 보면 크기가 NoMansLandSize인데, 값은 4바이트이다. 사용자가 요청한 메모리 크기에 비례해서 채워지는 0xCD와 0xDD에 비하면 노출 빈도가 아주 작은 셈이다. 특히 0xBD는 0xFD보다도 더욱 듣보잡인 듯..

애초에 얘는 사용자가 건드릴 수 있거나 건드렸던 공간이 아니며 그 반대이다. 사용자는 0xCD로 채워진 공간에다가만 값을 집어넣어야지, 앞뒤  경계를 나타내는 0xFD를 건드려서는 안 된다.
CRT 라이브러리의 디버그용 free/delete 함수는.. 힙을 해제할 때 이 0xFD로 표시해 놨던 영역이 값이 바뀌어 있으면 곧장 에러를 출력하게 돼 있다.

그리고 예전에 메모리를 해제해서 몽땅 0xDD로 채워 놨던 영역도 변조된 게 감지되면 _CrtCheckMemory 같은 디버깅 함수에서 곧장 에러를 찍어 준다. 그러니 0xDD, 0xFD, 0xBD는 모두 오류 검출이라는 용도가 있는 셈이다. 0xCC와 0xCD 같은 쓰레기값 영역은 쓰지도 않고 곧장 읽어들이는 게 문제이지만, 나머지 magic number들은 건드리는 것 자체가 문제이다.

그리고 얘들은 heap 메모리를 대상으로 행해지는 점검 작업이다. 이런 것 말고 스택 프레임에다가 특정 magic number를 둬서 지역변수 배열의 overflow나 복귀 주소 변조를 감지하는 것은 별도의 컴파일러 옵션을 통해 지원되는 기능이다. 요것들은 힙 디버그 기능과는 별개이며, 보안 강화를 위해 release 빌드에도 포함되는 게 요즘 추세이다.

이상이다.
파일 포맷 식별자 말고 메모리에도 디버깅을 수월하게 하기 위해 쓰레기값을 가장한 이런 특수한 magic number들이 쓰인다는 게 흥미롭다. Windows의 Visual C++ 외의 다른 개발 환경에서는 디버깅을 위해 어떤 convention이 존재하는지 궁금해진다.

사실, 16진수 표기용인 A~F에도 모음이 2개나 포함돼 있고 생각보다 다양한 영단어를 표현할 수 있다. 거기에다 0을 편의상 O로 전용하면 모음이 3개나 되며, DEAD, FOOD, BAD, FADE, C0DE 정도는 거뜬히 만들어 낸다. 거기에다 FEE, FACE, FEED, BEEF 같은 단어도.. 유의미한 magic number나 signature를 고안하는 창의력을 발산하는 데 쓰일 수 있다.
그러고 보니 아까 0xFEEE도 원래 free를 의도했는데 16진수 digit에 R은 없다 보니 불가피하게 0xFEEE로 대충 때운 건지 모르겠다.

Posted by 사무엘

2021/02/11 08:36 2021/02/11 08:36
, , , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1853

반비례 함수가 쌍곡선인 이유

두 초점 A, B가 있을 때 A에서의 거리와 B에서의 거리의 차가 동일한 점들의 집합을 쌍곡선이라고 한다. x^2 - y^2 = a 이런 음함수로 정의되며, 그래프를 그려 보면 곡선이 둘 그어지는 것이 특징이다.
그 반면, 합이 동일한 점들의 집합은 잘 알다시피 타원이며, x^2 + y^2 = a 꼴로 정의된다.

그런데 y=a/x, 다시 말해 xy = a 꼴인 반비례 함수는 x^2나 y^2처럼 단일 변수의 제곱이 존재하지 않는다. 하지만 우리는 이게 이차곡선인 쌍곡선의 표준형을 45도 돌린 형태라고 얼추 알고 있다.
어째서 그런 것일까? 수학적으로 더 엄밀히 증명해 볼 수는 없을까?
반비례 함수를 회전 행렬을 이용해서 45도 돌린 뒤, 이 함수가 쌍곡선 표준형과 동치임을 보이면 될 것이다.

45도일 때는 cos와 sin의 값이 sqrt(2)/2로 동일하다. 그렇기 때문에 (x, y)라는 점은 45도 회전하고 나면

사용자 삽입 이미지

요렇게 된다. 그럼 다음으로 45도 돌아간 x', y'를 기반으로 우리의 목표인 쌍곡선 방정식을 재구성하면 된다.
그러면 기존의 x, y 변수를 없애야 하는데, 위의 식을 그대로 제곱해서 빼기만 해도 x'^2 - y'^2 = -2xy로 놀랍게도 x^2와 y^2이 소거되어 없어진다. 이는 앞서 살펴보았듯이 각도가 45도여서 cos와 sin의 함수값이 서로 동일한 덕분에 가능한 일이다.

마지막으로 남은 xy야 원래 반비례 그래프의 정의상 a로 치환하면 되니 금방 처리된다.
그러면 x'^2 - y'^2 = -2a가 되고 쌍곡선과 동일함이 입증된다. 뭔가 허무해 보이지만.. 이차곡선 중에서 x나 y의 제곱이 없는 식은 이렇게 쌍곡선으로 귀결된다.
45도가 아닌 다른 각도라면 기존 x, y가 이렇게 쉽게 소거되지 않기 때문에 문제가 이런 식으로 단순하게 풀리지 않게 된다.

가만히 생각해 보니, 애초에 Ax^2 + Bxy + Cy^2 + Dx+Ey+F = 0에 대해서 그래프의 모양을 결정하는 판별식도 있다. A,B,C 중 적어도 하나 이상은 0이 아닐 때, B^2 - 4AC가 0이면 이 그래프는 포물선이요, 음수이면 타원 또는 원, 양수이면 쌍곡선이 된다. 구체적인 유도 과정은 쉽지 않을 텐데.. 이거 정도면 중등 교육과정 범위에 있다.
그러니 xy=1이야 B만 비영이고 A, C는 0.. 판별식 값은 당연히 양수가 되고 쌍곡선으로 귀결된다. 오오~~

판별식의 형태가 1계수 이차방정식의 근 판별식과도 매우 유사하다. 이차방정식의 경우 A만 비영이라는 조건이지만, 이차곡선 내지 원뿔곡선 방정식의 판별식은 아까 상술하였듯이 A,B,C 중 아무거나 하나 이상만 비영이면 된다.

그리고 A부터 F까지 아무 숫자나 집어넣는다고 해서 원뿔곡선이 튀어나오는 게 아니다. 상수항이 0이거나 하면 원이 극도로 작아져서 그냥 점이 되기도 하며, 쌍곡선은 점근선을 나타내는 직선 두 개로 귀착된다. 당장 xy=0만 해도 x축과 y축을 동시에 나타나내는 직선이 되니까.. 그럼 다음으로 포물선은..? 평행한 두 직선이 돼 버린다.
이차방정식이 x^2+1 = 0 같은 경우 실수 근이 존재하지 않는 것처럼.. 이것의 이변수 상위 호환인 원뿔곡선 방정식도 실수 범위에서 공집합이 될 수도 있다.

이 개념을 degeneracy(축퇴.. 축 쪽으로 퇴화)라고 부른다. 뭔가 행렬에서 행렬식의 값이 0이 돼 버리는 상황 같은 느낌이 들지 않는가? 계수가 주어졌을 때 축퇴 여부를 판별하는 판별식도 있다. 이건

(b^2-4ac)f + ae^2 - bde + cd^2

으로, 곡선 종류 판별식을 포함하면서 다소 복잡한 편이다. 이걸 유도하는 건 확실하게 중등 이상의 더 어려운 영역이며, 더 추상적인 수학 개념이 동원된다. 딱 봤을 때 각 항들에 변수가 2개가 아니라 3개씩 곱해진 것부터가 매우 인상적이다.

쌍곡선에서 시작해서 이차곡선에 대한 더 원론적인 얘기로 주제가 옆길로 좀 샜는데.. 다시 쌍곡선 얘기를 하며 글을 맺겠다.
반비례 그래프는 xy=a, 즉 x의 역수를 구하는 함수인지라 y=-x의 그래프에 대칭인 쌍곡선이 튀어나온다. e^x가 도함수가 자신과 동일한 함수라면, a/x는 역함수가 자신과 동일한 함수이다. f(f(x)) = x가 성립하는 게 어찌 보면 not이나 xor 연산 같아 보이기도 하다..

원의 방정식이 그 정의상 (cos(t), sin(t))라는 매개변수로 표현될 수 있는 것처럼 쌍곡선의 방정식은 (cosh(t), sinh(t))라는 매개변수로 표현될 수 있다. cosh와 sinh의 배치가 바뀌면 쌍곡선의 위치가 상하 또는 좌우로 바뀐다.

그리고 원의 방정식이 y=sqrt(a-x^2) 같은 꼴로 양함수로 표현될 수 있는 것처럼 쌍곡선의 방정식은 y=sqrt(x^2+a)의 꼴로 표현될 수 있다. a의 부호가 무엇이냐에 따라 쌍곡선의 배치(상하 또는 좌우)가 바뀐다. 한편으로 저 모양만 봐도 x의 값이 너무 작거나 커지면 y=x에 가까워질 소지가 다분해 보임을 알 수 있다.

Posted by 사무엘

2021/02/09 08:37 2021/02/09 08:37
, , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1852

1. 신호등이 있는 일반 도로

  • 애매한 비보호 좌회전 대신 감흥식 좌회전을, 애매한 황색 점멸 횡단보도 대신 보행자 작동 신호등을 더 늘림
  • 교차로의 노란불 딜레마를 해소하기 위해, 교차로 통과 결심 지점을 자그맣게 어떤 형태로든 표시한다. 즉, 부드러운 정지 제동이 가능한 특정 지점을 시속 60으로 이미 지났다면, 이제 신호등이 갑자기 노란불이 되더라도 그 속도 이상을 유지하면서 교차로도 통과하라는 뜻이다.
    비행기 이륙 결심 속도와 비슷한 개념이다. 이건 진출 방향별 분홍-초록 컬러 차선 같은 발명품이 되지 않을지 개인적으로 기대한다.. -_-;;
  • 교차로에서 ↑→가 같이 있는 곳, →만 있는 곳, 그리고 →와 ↑(X)가 있는 지점들의 의미를 명확히 해서 이로 인한 분쟁이 발생하지 않게 해야 한다. 우회전 하려는 뒷차를 비켜 줘야 하는 때가 언제인지를 말이다.
  • 커브나 오르막 바로 다음에 횡단보도나 교차로가 나오는 정도의 상황이 아니라면, 구간 단속이나 극단적인 속도 제한을 폐지한다. 그리고 이런 단속도 진짜로 곧 빨간불로 바뀌기 직전에만 스마트하게 시행함.
  • 어린이 보호 구역에서의 특별 감속은 평일에 애들이 실제로 등하교 하는 날짜와 시간대에만 시행한다. 그리고 속도 제한은 완화하고, 여기 주변에서의 불법 주정차를 더 강하게 단속하고 가중 처벌한다.
  • 자동차 신호등에도 파란불이나 빨간불에 남은 시간을 어떤 형태로든 표시하게 한다.

과속 하던 차가 불법 유턴 내지 비보호 좌회전 하는 차와 쾅 부딪혔을 때 과실 비율이 어찌 되느냐 하는 건 블랙박스 영상들 좀 본 사람한테는 정말 뻔한 클리셰일 것이다. 오목을 3과 4를 동시에 놔서 이기는 것만큼이나 흔한.. 전형적인 사고 패턴이라 하겠다.

2. 고속도로

  • 전국의 고속도로 최대 속도 제한을 150~180 정도로 상향, 현실화. 비현실적인 캥거루 감속이라는 게 없게 한다.
  • 그 대신 구간 과속 단속을 구현할 정도의 기술력으로, 지정차로 단속을 더 강하게 시행한다. 저속으로 1차로 지속 주행 차량한테 상품권. 칼치기뿐만 아니라 우측추월 칼치기를 강요하는 차량한테도 분명하게 과실 때림.
  • 진출로가 막혀서 정체 행렬이 굉장히 길게 이어져 있는데.. 정작 실제 분기 지점은 차들이 별 정체도 없고 긴 간격으로 아주 여유롭게 가고 있는 게 보인다. 이 정도면 새치기· 끼어들기를 하는 차만 나쁘다고 탓할 게 아니라 앞에서 빨리 빨리 가 주지 않고 있는 차에게도 책임을 좀 물어야 한다고 여겨진다.

3. 사고 시

  • 예측 불가능하게 갑자기 툭 튀어나오는 무단횡단자, 자라니 따위한테는 무관용. 사고 나도 운전자에게 실드 쳐 줌.
  • 음주운전은 단속에 걸렸을 때 처벌을 더 강화할 필요는 없지만 인명 사고를 냈을 때는 진짜 반 죽여 놓도록 처벌 강화.

모든 교통법규의 핵심은: "니가 거기에 재수없게 있다가 부딪친 게 잘못이다"가 아니라 "니가 이 규칙을 어기면서 거기에 있다가 부딪친 게 잘못이다"가 되게 하는 것이다. 또한, 차로 변경 없이 직선으로 쭉 고속 주행하는 차의 편의를 최우선적으로 봐 주는 것을 원칙으로 삼고 정책을 짠다.

앞에 아무 장애물이 없고 시야 확보되고 탁 트인 고속도로에서야 시속 180~200도 밟는다. 하지만 옆에서 뭐가 '합법적으로' 튀어나올지 모르는 골목길에서는 시속 30도 안 밟고 일시정지까지 하면서 언제라도 정지 가능하게 까치발 자세로 굴러가며 대비하는 것이 바로 안전운전이다.

또한 교통 시스템은 운전자에게 멀뚱멀뚱 신호대기가 아무 의미 없는 삽질 뻘짓이라는 생각이 들지 않게 해야 한다.
보행자는 자기가 있다는 티를 충분히 내도록 하고, 차가 브레이크 밟는 일이 없도록 협조해 줘야 한다.

4. 예방과 처벌

  • 미성년자가 성인을 거짓 사칭하거나 신분증을 위조해서 술· 담배를 샀는데 왜 편의점만 처벌하고 애새끼들은 처벌을 안 하는가?
  • 과적 화물차를 적발하면 왜 운전자만 처벌하는가? 과적을 부추기고 강요한 화주는 왜 강하게 처벌하지 않는가? 과적을 안 하는 게 바보짓이라는 관행 자체를 근본적으로 뿌리뽑을 생각을 왜 안 하는가?

이거 마치 성경에서 요한복음 8장의 간음하다 붙잡힌 여인 이야기를 읽으면서.. “왜 여인만 있고 같이 있던 남자는 어디 갔나?”라고 의문을 품는 것과 비슷해 보인다..;;

(1) 과적의 경우 경찰청의 단속 방식과 도로 공사의 단속 방식이 다르고 측정 장비조차 서로 연계되지 않는다고 수 년 전부터 뉴스 고발 프로에서 지적했었는데.. 이제 법과 제도가 좀 개선됐는가 모르겠다.

(2) 화물차는 과적뿐만 아니라 주행 중인 트럭에서 화물이 굴러떨어져서 주변 차가 날벼락을 맞는 사고가 생각보다 자주 발생했다. 그렇다 보니 몇 년 전부터 이것도 중과실로 인정될 정도로 법이 바뀌었는데.. 그것뿐만 아니라 판 스프링이 떨어졌다가 퍽 튀어올라서 사람을 잡은 사고도 지금까지 한두 건 발생한 게 아니었다.
이래저래 민폐 끼치는 방식이 참 다양한데.. 처벌 강화 말고는 딱히 답이 없는 것 같다.

(3) 그리고 자동차는 술만큼이나 미성년자에게 넘겨 줘서는 절대로 안 되는 위험한 물건이다. (우리나라야 총기는 없으니..)
그런데 신원을 제대로 확인하지 않고 애들한테 차를 덥석 빌려준 렌터카/카셰어링 업체들은 술을 잘못 판 편의점을 조지듯이 강하게 처벌받고 있나 모르겠다.

아니, 형사 처벌이 없더라도, 대여자 신원을 제대로 확인하지 않아서 사고가 난 것에 대해 보험사에서 보상을 전혀 안 해 버리면 그것만으로도 자동차 대여업자들은 무서워서 몸을 사리게 될 텐데.. 도대체 왜 이런 부조리가 개선되지 않고 있는지 개인적으로 무척 궁금하다.

흉악범, 음주운전 가해자에 대한 처벌이 너무 약한 것, 무단횡단자에 대한 처벌이나 교통사고 과실 부과가 너무 약한 것, 정당방위 인정이 비현실적으로 너무 좁은 것들은 더 말하면 입만 아프니 더 말을 말자.

5. 교통 관련 법규가 다른 분야의 법과 닮은 부분

(1) 산에서 무단으로 각종 나물을 채취하지 말라고 "국유림 나물 채취는 불법이고, 사유림 나물 채취는 도둑질입니다" 이런 표어를 만들어 놓은 것을 본인은 유튜브에서 본 적이 있다.
이건 주차로 치면 각각 불법 주차와 부정 주차에 정확하게 대응한다. 전자는 그 누구도 차를 세워서는 안 되는 곳(길가의 황색 실선)이고, 후자는 차를 댈 수는 있지만 그게 니 차는 아닌 곳이니 말이다.

(2) 군대에는 형법상의 중징계를 받는 항명죄라는 게 있고(군형법 제44조), 그것보다는 가벼운 징계를 받는 지시 불이행(군인복무기본법 제25조 복종 의무 위반)이라는 게 있다.

도로교통법에서 말하는 신호와 지시도 이와 완전히 같지는 않지만 얼추 비슷한 관계인 것 같다.
신호등은 명령인 게 명백해 보이는데, 이뿐만 아니라 각종 '좌회전/유턴 금지, 추월 금지, 일방통행, 안전지대' 같은 지시 표지판들도 신호등과 동급의 강제성을 지닌다.

비록 이런 표지판들은 단속 카메라가 달려 있지는 않지만, 이런 걸 어겨서 사고가 나면 신호 위반과 완전히 동등한 12대 중과실 사고로 처리되므로 절대적으로 주의해야 한다. 그러니 '신호 위반'이라는 건 애초에 '신호/지시 위반'이라고 이해하는 게 더 정확하다.
아울러, 경찰관의 교통 통제 신호도 '지시'로 간주된다. 이 지시는 심지어 신호등보다도 적용 우선순위가 더 높다.

Posted by 사무엘

2021/02/09 08:35 2021/02/09 08:35
, , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1984

서울 지하철의 건설과 개통 내력

서울 지하철의 건설 형태는
"1 / 2 / 3,4 / 5,6,7,8 / 9 (,10,11,12)"호선.. 이렇게 나뉘었다고 생각하면 된다.

1.
1960년대 말, 서울시의 높으신 분들은 이렇게 서울시가 팽창하고 인구가 증가하다가는 시내의 교통은 체증 때문에 완전히 끝장이 날 것이라고 우려했다. 그래서 선택한 돌파구는 지하철.. 우리도 외국의 대도시들처럼 땅 아래로 길을 파서 지하철을 건설해야겠다는 결론을 내렸다.

그때까지 서울 시내에는 노면전차라는 게 있었다. 하지만 경영 수지가 안 좋아 적자가 쌓여 가고, 차량과 시설의 노후화도 심한 노답 상태였다. 얘는 지하철 건설을 위한 시범타로 완전히 폐선· 퇴출되었다.
전차가 없어진 종로 도로를 파헤쳐서 몇 년 동안 극심한 버스 혼잡과 교통 체증을 감내한 끝에, 서울 최초의 지하철 1호선은 철도청 광역전철 경인(인천)/경부(수원)/경원선(성북)과 직결된 독특한 형태로 건설되고 개통됐다. 차량 운행을 철도청(현 코레일)과 서울 지하철 공사(서울 교통 공사)라는 두 주체가 공동으로 하기 시작했다.

차량은 그 당시 유행이던 중문 달린 식빵 모양 '초저항'(초기 저항 제어 방식 전동차) 차량을 일본으로부터 수입해 와서 굴렸다. 철도청은 차량에 파란 도색을, 서지공은 빨간 도색을 사용했다.

사용자 삽입 이미지

얘는 일본의 신칸센 0계 전동차만큼이나 우리나라 철도 역사의 상징인 매우 귀중한 차량이다. 그렇기 때문에 코레일과 서교공 모두 자기네 초저항 차량을 내구연한 경과로 인해 퇴역한 뒤에도 한 량씩 자기 방식으로 도색해서 정태보존 중이다. (각각 철도 박물관, 신정 차량기지 내부)

저런 식빵 모양의 디자인은 비슷한 시기에 일본 현지에서 다닌 도쿄 지하철 5000계 전동차에도 그대로 남아 있다. 단지, 차폭은 일본 내수인 1067 협궤가 아니라 1435 표준궤로 커진 것이다. 이 때문에 한국의 초저항 전동차는 일본의 철덕들에게도 관심을 받고 있다.

사용자 삽입 이미지

초저항 전동차의 주요 특징 중 하나는 바로 전방 중앙에 출입문이 있다는 것이다. 필요한 경우, 전동차를 그대로 중련 편성해서 기관사가 아니라 승객이 객차 사이를 지나다닐 수 있게 하려는 의도였다!

지하철 1호선이 첫 개통한 날엔 대통령까지 참석하는 성대한 개통식을 치를 예정이었지만.. 하필 개통식 당일의 이전 행사에서 영부인 육 영수 여사가 괴한에게 피격 당하는 바람에 지하철 개통식은 대통령 없이 아주 우울하고 어수선한 분위기에서 치러지게 됐다. 그리고 서울 시장도 경질되고(양 택식 → 구 자춘) 향후의 지하철 건설 계획까지 확 바뀌게 됐다.

2.
서울 지하철 2호선은 1980년부터 84년까지 점진적으로 개통하면서 거대한 순환선으로 만들어졌다. 이때 굉장히 큰 변화가 생겼다.

  • 고유 노선색 패턴 (2호선은 초록색)
  • 저항 제어보다 조금 더 발전한 초퍼 제어 방식 전동차 (MELCO). 국영 공작창이 아닌 민간 기업 중심으로 차량 생산 시작
  • 매큔-라이샤워 로마자 표기법
  • 노인 무임승차(!!!)
  • 지금과 같은 지하철체
  • 최초의 우측통행 (조금 뻘짓 같지만), 최초의 지하철간 환승역 (신설동)
  • 8량 증결 (처음엔 6량 1편성이었음.. 역들의 건설만 10량 기준으로 해 놓고)

이 정도면 서울 지하철의 실질적인 기틀은 2호선 때 완전히 잡혔다고 봐도 되겠다.
용답 역 근처에 있는 군자 차량기지는 서울에서 중심부에 가장 가까이 있는 지하철 차량기지이다. 그러면서도 창동이나 구로 기지와 달리 이전 계획도 없고, 오히려 여기 주변에 서울 교통 공사 본사와 종합 관제센터까지 들어서 있다.

아, 그리고 1호선이 지상 광역전철과 직통 운행하는 지하철을 선보였다면, 2호선은 유의미한 구간을 계속해서 지상 고가로 달리는 지하철? 도시철도?를 최초로 선보였다. 타 노선들은 한강을 건널 때 내지 외곽 종점 차량기지에 다 왔을 때에만 잠시 지상에 나온다는 점을 생각해 보면, 강변-뚝섬이라든가 신대방-대림 지상 구간은 서울 시내에서 보기 드문 형태이다.

3-4.
3호선과 4호선은..

  • 최초로 Y자형 분기(1호선)나 O자형 순환(2호선)이 아닌, 단순한 I자 선형..;;
  • 서울 올림픽에 대비하여 자금의 압박에도 불구하고 최초로 두 노선이 동시에 건설· 개통되어 서울 중심부를 X자로 관통했다. 충무로 역은 최초로 2개 노선이 동시에 건설된 환승역이다.
  • 일본물이 아닌 유럽물을 먹은 광폭형 GEC 초퍼 전동차가 이때 도입돼 들어왔다.
  • 올림픽을 염두에 둬서 그런지 인테리어를 1· 2호선보다 더 신경쓴 역들이 제법 등장했다. 경복궁, 교대, 동대문운동장처럼..
  • 신호 시스템이 ATS보다 더 정교하고 발전된 ATC로 바뀌었다.
  • 얘들이 등장한 시기부터 전동차들이 드디어 10량으로 증결됐다.
  • 얘들은 일산, 분당, 과천 이렇게 새로 건설된 광역전철들과 직통 운행을 시작했다.

참고로 80년대 중반 올림픽 준비의 산물들로 다른 분야로는: 올림픽대로, 현대 그랜저, 유선형 새마을호 열차가 있다.
지금으로서는 상상이 안 되지만 과거에는 2호선에도 1호선의 초저항 전동차, 또는 3-4호선의 GEC 초퍼 전동차가 잠시 다닌 적이 있다. 그 반면, 2호선의 MELCO 초퍼는 2호선 외의 타 노선을 다닌 적이 없다.

5-8.
이제 1990년대에 서울 2기 지하철 노선 4개가 한꺼번에 계획되고 건설됐다. 세부적으로는 이것도 95~96년 사이(5호선 전체, 7호선 강북 구간, 8호선 남쪽 구간)와 99~01년 사이(6호선 전체, 7· 8호선 나머지 구간)의 두 타이밍으로 나뉜다만..
얘는 지난 15년간의 지하철 건설 노하우를 바탕으로 다음과 같은 변화가 생겼다.

  • 1기 시절보다는 환승거리를 최대한 줄이는 쪽으로 역들이 만들어졌으며, 심지어 더 미래에 건설할 3기 지하철까지 염두에 두고 환승 통로와 노반을 미리 만들어 놓았다! (5-9 여의도역처럼)
  • 전동차 외형의 표준화
  • 자갈 대신 콘크리트 노반
  • 재래식 삼발이 대신 깔끔한 개집표기, 무려 하저터널,
  • 롤지 대신 LED 전광판
  • 저항/초퍼보다 더 발전된 VVVF 제어: 자동차 내연기관으로 치면 가변 밸브 개폐량/개방 시간(VVL/VVT) 같은 기술을 떠올리면 되겠다.
  • ATS/ATC보다 더 발전된 ATO 신호 시스템. 차장을 생략한 1인 승무

이렇게 1기 지하철에 비해 정말 정말 많은 부분이 발전했다.
이때는 차량 외형은 다들 비슷해졌지만, 내부의 VVVF 인버터는 제대로 국산화되지 않았기 때문에 제조사별로 ABB, 미쓰비시, GEC 등 갖가지 개성 넘치는 전자악기 소리를 가속 구동음으로 들을 수 있었다. 이게 1990년대의 로망이다. 2기는 1기와 달리, 시각 대신 청각적으로 즐길 것이 다양해진 셈이다.

사용자 삽입 이미지

지하철 건설이란 게 워낙 재정 등골 브레이커이다 보니 2기 지하철을 만들 때는 어떻게든 원가를 줄이려는 노력을 높으신 분들이 했는데, 그 아이디어 중 하나가 2기 지하철부터는 아예 무인 운전을 시키는 것이었다.

하지만 테스트를 해 보니 자동 운전 시스템이 승강장 제 위치에 정차를 정확히 못 했다. 또한 이때는 아직 스크린도어도 없어서 완전 무인 운전을 하기엔 여러 애로사항들이 즐비했다. 이 때문에 현실에서는 2인 승무에서 차장만 뺀 1인 승무로 줄이는 수준에서 머물렀다.

서울 지하철 5호선의 최초 개통 구간이 왕십리-상일동이었으며, 천호대로 구간이 이때 파헤쳐졌다가 복구되면서 국내 최초의 시내 중앙 버스 전용 차로로 탈바꿈한 것은 유명한 일화이다.
응답하라 1997에서 나름 고증을 반영한답시고 지하철 노선도에서 5~8호선은 하얗게 지워 놨던데 그건 오류이다.
그 시절엔 5~8호선도 점선으로 그려 놓고 "건설 중, 개통 예정"이라고 표시해 놓는 게 올바른 고증이다. -_-;;

처음에는 5~8호선만 운영하는 '서울 도시철도 공사'라는 회사가 따로 만들어졌다. 그런데 한 도시의 지하철에 사철도 아니고 공기업이 둘이나 있는 건 꽤 이례적인 경우였기 때문에 2017년부터는 두 회사가 하나로 합쳐져서 서울 교통 공사로 바뀌었다.
회사가 둘이서 따로 놀던 시절엔 한 회사 구간에서 파업이 벌어져도 다른 회사 노선은 영향이 없었는데.. 지금은 파업 발생 시에 지하철 1~8호선이 몽땅 멈춰 버릴 가능성이 생겨 있다.

9.
다음으로 서울 3기 지하철은 계획대로라면 9~12호선이 추가로 건설됐어야 했다. 하지만 외환 위기와 IMF, 이로 인한 긴축 재정 처방 때문에 지하철 건설 계획은 대부분 칼질 당했으며, 이 때문에 5~8호선 건설 때 미리 준비를 해 놨던 환승역 건설 공간과 노반도 상당수 잉여로 전락하게 됐다.;;
3호선과 7호선의 연장(오금 2010 / 부평구청 2012), 그리고 강남의 횡축 노선인 9호선만이 살아남았다. 나머지는 2010년대 이후에 서울 외곽 구간만이 광역전철(10은 신안산선, 11은 신분당선) 아니면 경전철(12는 우이신설선)로 실현됐다.

사용자 삽입 이미지

9호선은 다음과 같은 점에서 큰 의의가 있다.

  • 광역전철이 아닌 단순 도시철도 지하철로서는 이례적인 전구간 급행열차 운행
  • 처음 건설 때부터 모든 역에 스크린도어 시공
  • 마분지 승차권의 완전 퇴출
  • 오 세훈 시장 서울 디자인 가이드라인이 적용된 덕분에 혼자 굉장히 이질적인 인테리어
  • 한국형 표준 전동차 규격. VVVF 인버터도 통합됐기 때문에 구동음은 대전 같은 최신 지방 지하철하고 pitch(음높이)만 다르지 음색은 같다.

그러므로 서울 지하철의 건설 계획이 대판 틀어진 계기는

  • 1기 지하철: 육 영수 여사 피격으로 인한 서울 시장 경질 (신설동 역 유령 승강장이 생긴 이유도 이 때문!)
  • 3기 지하철: IMF ...;;

라고 정리된다. 그리고 차량 운용 계획이 실현되지 않은 것은..

  • 1호선: 유동적인 열차 중련 편성 (그런 것 필요없고 지금은 언제나 10량 꽉꽉 채움..)
  • 2기 지하철: 무인 운전 (현실은 시궁창. 1인 승무만으로 감지덕지)

이렇게 정리된다.
유동적인 열차 중련 편성은 무인 운전하고는 전혀 어울리지 않는 운용 계획이라는 게 흥미롭다. 철도 운영 이념이 세월에 따라 이렇게 바뀌었다.

Posted by 사무엘

2021/02/06 08:35 2021/02/06 08:35
, , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1851

1. DLL 주소 재배치와 ASLR의 관계

Windows XP 내지 Vista 이후로 (1) 커널 API와 C 런타임 라이브러리 함수 심벌들이 한 DLL 몰빵이 아니라 분야별로 재분류되어 배치되기 시작한 것, (2) 시스템 DLL들이 이제 전혀 rebase되지 않고 고정된 단일 preferred base 주소를 갖기 시작한 것을 보면 참 격세지감이 느껴진다.

위의 둘은 (1) 자잘한 DLL 여러 개보다 큰 DLL 하나가 더 효율적이다(선박처럼??). (2) DLL들은 로딩되는 주소가 겹치지 않게 빌드 후에 반드시 rebasing을 해 줘라
이런 전통적인 고정관념을 역행하는 변화이기 때문이다.

보안 강화를 위해 10여 년 전 Windows Vista 때부터 ASLR (시작 주소 랜덤화)이 도입되면서 DLL은 물론이고 EXE조차도 반드시 자기 preferred base에 고정적으로 로딩이 되지 않게 되었다. 이 때문에 요즘은 EXE도 과거 Win32s 프로그램들처럼 끝에 재배치 정보가 다시 포함돼 들어가고 있다.

하지만 이런 ASLR을 위한 재배치 때는 말 그대로 메모리 오프셋 수정만 행해질 뿐, 재배치의 치명적인 페널티라고 여겨지는 가상 메모리 페이지 파일 재기록이라든가 재사용 불가(여러 프로세스에서 동일 DLL 로딩 시에도 shallow가 아닌 deep copy 발생) 까지 발생하지는 않는다. 운영체제의 보안 기능이 그 정도로 바보는 아니다.

그러므로 오늘날은 DLL을 미리 rebase 하건 안 하건 실행 성능이 달라지는 것은 없다. rebase를 해도 이익을 얻는 것은 없지만 반대로 손해를 보는 것 역시 없다. rebase라는 게 빌드 타임이 아닌 런타임의 영역으로 바뀐 셈이다.

정말 재수가 없어서 엄청 많은 자잘한 DLL들이 로딩되다 보니 한 DLL이 프로세스 A에서는 ASLR 배당 주소로 로딩됐지만 프로세스 B에서는 그 주소로 로딩이 못 되게 됐다면.. 그때는 통상적인 페널티가 부과되는 재배치가 발생할 것이다. 하지만 광대한 주소 공간을 자랑하는 64비트 환경에서는 그럴 가능성이 더욱 희박해졌다.

2. EXE를 LoadLibrary 하기

LoadLibrary 함수는 실행 가능한 코드가 담긴 DLL을 불러오거나 혹은 EXE/DLL로부터 리소스를 얻고자 할 때 즐겨 쓰인다.
그런데 여기서 의문이 든다. LoadLibrary를 호출해서 exe의 단순 리소스가 아니라 코드를 내 프로세스 공간에 가져와 실행하는 게 가능할까?

사실, 기술적으로 볼 때 EXE와 DLL의 차이는 그리 크지 않다. 심지어 EXE도 DLL처럼 심벌 export를 할 수 있다.
그리고 EXE를 LoadLibrary로 그냥 쌩으로 불러와도, 의외로 일단 성공은 한다. GetProcAddress를 해서 심벌을 요청하면 주소값이 돌아오기까지 한다.
하지만 그 함수를 호출해 보면 십중팔구 access violation 에러가 난다. 여기서 대부분의 사람들은 '안 되나 보다'라고 생각하고 단념하게 된다. 왜 이런 현상이 발생하는 것이며, 문제를 해결할 방법은 없는 걸까?

DLL이 아닌 EXE를 LoadLibrary 하면 운영체제는 얘를 반쯤 데이터로 취급하는가 보다. GetProcAddress를 호출했을 때 심벌 검색 결과를 되돌려 주지만 그 포인터가 가리키는 코드를 실행 가능한 상태로 만들어 놓지는 않는다.
특히 (1) 주소 재배치와 관련된 그 어떤 조치도 취하지 않는다. 구체적으로는.. EXE가 사용하는 import table의 주소를 패치하지 않기 때문에 그 EXE의 코드가 실행되면서 Windows API 같은 걸 호출하면 그대로 뻑이 나게 된다.

그리고 (2) EXE의 진입점 함수를 전혀 실행하지 않는다.
EXE건 DLL이건 무조건 맨 먼저 실행할 부분을 가리키는 진입점이란 게 있는데.. 그게 EXE는 int func() 형태이고, DLL은 BOOL func(HMODULE, UINT, PVOID) 형태이다.

즉, EXE는 처음엔 아무 인자 없이 실행됐고 C 라이브러리가 GetStartupInfo 같은 API 함수를 호출해서 실행 인자를 준비한 뒤에 main이나 WinMain을 또 호출하는 형태이다. 그러나 DLL은 진입점 함수의 형태가 DllMain과 완전히 동일하다. 즉, DLL_PROCESS_ATTACH 같은 이벤트 명칭은 이 함수의 호출 인자가 아니면 딴 데서 알아낼 곳이 없다.
LoadLibrary는 원래 DllMain을 호출하게 돼 있는데 EXE는 받아들이는 함수 prototype이 다르므로 아예 호출을 안 하는 것이다.

그러므로 LoadLibrary된 exe의 코드를 강제로 실행한다면 IAT 테이블의 주소가 패치되지 않고 C 라이브러리가 전혀 초기화되지 않은 상태에서 덥석 실행된다. 그 함수에서 내부적으로 전역변수 C++ 객체 같은 걸 사용한다면.. 역시나 제대로 실행되지 못하고 높은 확률로 뻑나게 된다.

IAT 주소를 패치하는 방법까지는 어느 용자가 찾아낸 게 인터넷에 이미 굴러다닌다. (☞ 링크) 이거 패치가 제대로 되려면 EXE는 애초부터 재배치 정보가 들어간 상태로 빌드돼야 한다.
하지만 각종 부작용 없이 C 라이브러리만 감쪽같이 초기화하고 EXE의 export 함수를 실행하는 건.. 굉장히 삽질스럽고 가성비가 낮다. 그냥 EXE와 DLL의 차이가 이러하며 LoadLibrary(EXE)가 기술적으로 왜 권장되지 않는지 이론으로만 알고 넘어가면 될 듯하다.

3. 재빠르게 대체된 파일에 대한 creation date 보정

응용 프로그램 중에는 안전을 위해 문서 저장 기능을 임시 파일을 생성하는 형태로 구현한 것이 있다.
기존 파일을 곧장 덮어써서 저장하는 게 아니라.. 임시 파일에다가 저장을 한 뒤, 기존 파일을 지우고 임시 파일을 기존 파일의 이름으로 바꾼다. 이렇게 하면 저장하는 중에 컴퓨터에 전기가 나가는 등의 이상 현상이 발생하더라도 최소한 기존 자료가 송두리째 날아가는 일은 막을 수 있다.

그런데 이렇게 기존 파일을 덮어쓰는 게 아니라 파일 자체를 딴 것으로 대체하는 식으로 저장을 하면 기존 파일이 갖고 있는 creation time이 보존되지 않게 된다. 그렇기 때문에 기존 파일의 creation time을 따로 얻어 놓은 뒤, 저장을 마친 새 파일에 대해서 creation time을 SetFileTime 함수로 따로 지정해 줘야 한다.

단, Windows NT 계열의 경우, 놀랍게도 보정 동작을 진작부터 지원하고 있었다. 어떤 프로그램이 A라는 파일을 삭제한 뒤에 다른 파일의 이름을 A로 신속하게 거의 곧장 변경한 경우, 그 파일에다가 삭제된 A의 creation time을 자동으로 지정해 줬던 것이다~!

이런 보정을 위해서는 파일 삭제와 개명 알고리즘에다가 삭제된 파일의 생성 시각을 백업해 놓고, 시간차를 감지해서 이 renaming이 기존 파일을 승계하는 동작인지 판단하는 등 여러 귀찮은 작업이 필요할 것이다. 하지만 마소에서는 임시 파일 방식으로 저장하면서 creation time을 관리하지 않는 프로그램이 많은 것을 감안하여 운영체제 차원에서 이런 보정 기능을 구현했다고 한다.

이 보정은 NT 계열에서만 지원되어 왔으며, 9x 계열에서는 존재하지 않는다.

4. 스레드 동기화 deadlock 자동 감지

복잡한 메모리 문제를 잡아내기 위해 C 라이브러리 차원에서 저런 다양한 안전 장치와 디버깅 편의 기능이 제공되듯, 멀티스레드 동기화 오브젝트에도 디버그 버전용은 데드락 정도는 assertion failure 에러를 내면서 곧장 감지하는 기능이 있으면 좋겠다는 생각이 든다.

“당신이 지금 취득을 위해 대기하려는 뮤텍스는 현재 다른 스레드가 잡고 있는데, 문제는 그 스레드도 지금 당신이 요 스레드에서 잡고 있는 뮤텍스를 얻으려고 대기 중이다. 그러니 이 상태로는 상호 무한 대기 교착 상태가 됨.”

이건 레퍼런스 카운트 기반인 오브젝트에서 순환 참조 오류를 감지하는 기능을 구현하는 것과 기술적으로 완전히 동급이다.
Hash 같은 컨테이너를 둬서 스레드 ID별로 각각 현재 진입해 있는 뮤텍스에 대한 기록을 관리하고, 뮤텍스 오브젝트를 감싸는 클래스에다가 현재 자신을 잡고 있는 스레드 정보도 같이 보관하는 정도의 수고만 하면 큰 어려움 없이 구현 가능하다.

하지만 PC용 프로그램에서 돌아가는 스레드의 개수가 무슨 할당된 동적 메모리 블록 개수처럼 많을 리는 없을 것이고, 프로그램의 응답이 멎었을 때 데드락 부위를 찾는 것은 도구의 도움 없이 도저히 못 할 일은 아닐 것이다. 유용성에 비해 저런 기능을 갖추는 건 속도와 메모리 오버헤드가 너무 커서 가성비가 맞지 않으니 데드락 자동 감지 기능은 운영체제나 프로그래밍 언어 런타임이 제공해 주지 않는 듯하다.

개인적으로 직장에서는 심지어 자기 스레드 자신의 실행이 끝나기를 기다리는.. C++ 오브젝트로 치면 delete this.. 무슨 자살이나 다름없는 deadlock도 경험한 적이 있었다.
프로그램의 실행이 종료되어 UnInit() 함수가 호출될 때는 백그라운드 작업 스레드에 대해서도 작업을 중단시키고 작업 스레드의 실행이 끝날 때까지 기다리게 했는데, 뭔가 로직이 꼬여서 작업 스레드에서 UnInit()를 호출하는 상황이 발생한 것이다.

Uninit이 무슨 loop 안에서 1초에 수십, 수백 번씩 실행되어서 성능이 중요한 함수인 건 아니다. 그러니 자기 자신이 무슨 스레드 문맥에서 실행되었는지 검사해서 deadlock을 피할 수도 있다.
하지만 그것보다는 Uninit이 스레드 함수가 아니라 의도했던 대로 main thread에서만 실행되도록 프로그램 구조를 고치는 것이 훨씬 더 나은 해결책이었다.

Posted by 사무엘

2021/02/03 19:36 2021/02/03 19:36
,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/1850

1. 프로그래밍 용어· 명칭과 타 분야 비교

  • 2의 제곱근 vs 제곱근(루트) 2: 어순의 차이로 의미가 달라지는 new operator/operator new, 함수 템플릿 vs 템플릿 함수 같은 C++ 용어와 상황이 비슷하다. 특히 다들 전자가 후자를 포함하는 편이기도 하다.
  • 전철역에서 논현, 신길, 양평: namespace가 필요한 좋은 예이다..;;; (1) 얘들은 고유명사 지명이 지역간에 충돌하는 사례이고 (2) 월드컵경기장이나 시청은 보통명사 시설명이 충돌하는 예이다.
    (3) 수색, 광명, 신촌 같은 건 지역이 아니라 일반열차 역과 지하철역이 충돌하는 경우이다. 그리고 (4) '회송'은 역의 이름으로는 쓰이지 않는(쓰일 수 없는) reserved word 정도에 대응할 것이다.
  • 배의 명칭 A급 B함/호(포항급 초계함 천안함, 올림픽급 타이타닉 호, 베헤모스급 배틀크루저 히페리온): 프로그래밍으로 치면 A는 타입명이고 B는 변수명이다.

2. 마침표와 세미콜론

우리는 년월일 날짜를 간략하게 표기할 때 2020. 10. 5. 같은 식으로 숫자 뒤에 마침표를 찍곤 한다. 이때 일을 나타내는 마지막 마침표도 생략하지 말고 반드시 다 찍는 것이 한글 맞춤법에 규정된 원칙이다. 각각의 점이 년, 월, 일을 나타내기 때문이다.

이는 마치 파스칼 언어에서는 세미콜론이 문장의 구분자(separator)인 반면, C/C++에서는 문장의 종결자(terminator)인 것과 비슷하다.
파스칼에서는 end나 else 직전에 등장하는 구문의 끝에 ; 이 생략되지만 C/C++은 그렇지 않다. 날짜 숫자의 뒤에다 찍는 .는 파스칼이 아닌 C/C++의 세미콜론과 같은 성격이라고 생각해야 한다.

3. 병렬화

같은 용량의 데이터가 있을 때 압축을 하는 것은 압축을 푸는 것보다 계산량이 훨씬 더 많은 어려운 작업임이 주지의 사실이다.
그 대신, 압축 "하기"는 CPU 멀티코어를 활용해서 속도를 쭉쭉 끌어올릴 수도 있는 반면, "풀기"는 그런 병렬화는 안 되고 그냥 단일 코어에서 linear한 작업에 의존할 수밖에 없다. 기껏해야 풀어야 하는 압축 파일 자체가 여러 개일 때에나 여러 CPU에다가 던져줄 수 있을 것이다.

C/C++ 파일을 빌드하는 절차도 이와 비슷해 보인다. '컴파일'은 아무래도 분산 처리와 병렬화가 가능하지만, 모든 결과물이 하나로 집약되는 '링크'는 그게 불가능한 최종 병목이 될 수밖에 없다.

4. 버퍼의 크기

일상적으로 무슨 모임 같은 데서(본인의 경우는 교회에서 청년부 모임 같은..) 인원수대로 프린트물이나 간식 같은 것을 준비해야 할 때가 있다. 평소에 모임 참석자가 얼마 정도 되는지에 대한 대략의 데이터는 있지만 딱 정확하게 몇 명인지는 알 수 없을 때는 준비물을 몇 개 정도 챙겨야 너무 남거나 모자라는 일이 없이 최대한 딱 맞을 수 있을까?

이건 나름 통계적인 노하우가 필요한 일이다. 가끔 모자라는 일이 발생해도 괜찮은지, 아니면 모자라는 일은 절대 없어야 하는지에 따라서도 전략이 달라진다. 프로그래밍으로 치면 static한 배열의 크기를 잡는 것과 매우 비슷해 보인다는 생각을 본인은 오래 전부터 했다. ㅎㅎ

문자열 클래스의 경우, 사소한 문자열까지 늘 동적 메모리를 할당하는 건 번거로우니 자체적으로 자그마한 배열도 갖고 있고, 그 배열 크기를 초월하는 긴 문자열을 배당할 때만 동적 메모리를 사용하게 하는 구현체도 존재한다. C++의 표준 string 클래스도 반드시 저렇게 동작해야 한다는 조건은 없지만 대체로 이런 식으로 구현된 걸로 본인은 알고 있다.

이런 것 말고도

  • 건물을 지을 때 이 정도 건물에서는 화장실에 변개를 몇 개 설치하는 게 좋을까?
  • 엘리베이터는 어느 정도 크기로 몇 개 설치하는 게 좋을까?
  • 이 정도 도로의 교차로 내지 횡단보도에서는 신호 주기를 어느 정도로 주는 게 좋을까?

같은 문제도 치밀한 공학 및 통계 계산의 산물이지 싶다. 동시에 사용하는 사람의 수가 최대인 시간대에 대기 시간이 너무 길어지지 않게 하는 한편으로, 나머지 한산한 시간대에 시설들이 사용자 없이 놀면서 발생하는 비효율도 최소화해야 하기 때문이다.

5. 훅킹

훅(hook) 내지 훅킹이란 컴퓨터 소프트웨어가 돌아가는 과정을 몰래 들여다보고 필요하면 변조도 하는 메커니즘을 말한다. 훅킹은 대체로 시스템 프로그래밍 분야에 속하며 꽤 강력한 고급 테크닉으로 간주된다.

(1) 메시지 훅
Windows에는 SetWindowsHookEx라는 엄청난 함수가 있어서 시스템과 응용 프로그램 사이에서 오가는 메시지들을 매우 수월하게 들여다볼 수 있다. 그러니 Spy++ 같은 프로그램을 만들 수 있다.
권한 문제만 없다면 심지어 다른 프로그램의 메시지를 들여다볼 수도 있다. 이 경우, 훅 프로시저가 내 프로세스가 아니라 그 메시지를 받은 프로세스의 문맥에서 실행된다는 점을 주의할 것. 32비트와 64비트별로 DLL을 따로 만들고, 프로세스 간의 통신 같은 잡다한 수고만 좀 해 주면 된다.

(2) API 훅
다른 프로그램이 그냥 기계어 수준에서 운영체제의 특정 함수를 호출하는 것을 감지하고, 그 함수 대신 내가 심은 함수가 호출되게 할 수 있다. C 언어 형태의 클래식 API가 제일 쉽고, COM도 결국은 CoCreateInstance 같은 함수를 훅킹하면 이론적으로 가능하다. 실행되는 기계어 코드를 변조하는 게 아니라 import 섹션 주소를 변조하는 고전적인 테크닉이 있다.

16비트 시절에는 API 훅을 시스템 전체에다 걸어서 운영체제 외형을 통째로 마개조 할 수도 있었지만 32비트 이후부터는 그 정도까지는 어렵다. 다만, 시스템 전체에다가 설치한 메시지 훅과 CreateRemoteThread 등 다른 어려운 테크닉들과 연계하면 API 훅도 어느 정도 global하게 설치하는 게 가능은 하다.
과거에 한컴사전이 GDI 그래픽 API에다가 훅을 걸어서 단어 자동 인식 기능을 제공했던 적이 있다. 마우스 포인터 주변의 화면 캡처 + 필기 인식이 아니다~!

(3) 패킷 훅
심지어 시스템 전체에서 오고 가는 네트워크 패킷을 모니터링 할 수도 있다. 이게 기술적으로 가능하니까 packet sniffer이라고 불리는 유틸리티들도 존재 가능할 것이다. 이에 대해서는 본인도 더 아는 게 없다.
macOS는 Windows와 달리 메시지 훅이고 API 훅 같은 건 존재하지 않는 것으로 본인은 알고 있다. 하지만 macOS라도 패킷 모니터링은 아마 가능할 것이다.

packet sniffer이라든가 심지어 VPN 툴 같은 건 어떤 API를 써서 어떻게 만드나 모르겠다. 신기한 물건이다.

Posted by 사무엘

2021/02/01 08:34 2021/02/01 08:34
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1849

1. 통일로

서울 역 북부에서 시작해서 서대문 역(5)과 독립문 역(3)을 찍고 지하철 3호선의 선형을 따라 고양· 파주 방면으로 가는 도로는 국도 1호선 구간인 한편으로 이름이 '통일로'이다.
이 길 자체는 오래전부터 있었지만 그게 고양과 파주까지 4차선 도로로 한데 뚫리고 '통일로'라는 이름까지 붙은 건 1972년 봄의 일이라고 한다. '통일호'라는 열차 이름은 1950년대 할배 때부터 있었지만, '통일로'는 박통이 붙인 이름이다.

그리고 바로 이 타이밍에 맞춰서 통일로의 종점에 임진각 관광지가 만들어졌으며, 통일촌이라는 민통선 마을도 생겼다. 그로부터 몇 달 뒤인 7월 4일엔 우리가 학교에서도 배우는 7· 4 남북 공동 성명이 발표됐다.
그러니 그때는 온통 통일, 통일 하던 분위기였다. 사람들은 이제 얼마 안 있으면 진짜로 남북 통일이 이뤄질 줄 알고 많이 들떴었다.

지금이야 서울에서 파주 임진각 방면으로 갈 때 강변북로에서 이어지는 자동차 전용 도로인 자유로, 혹은 최근에 개통한 서울-문산 고속도로(17)가 즐겨 쓰인다.
자유로는 통일로 이후로 딱 20년이 지난 1992년에 개통했으며, 한강과 임진강이 합류하는 지점에 오두산 통일 전망대가 같이 만들어졌다는 점이 특징이다.

자유로나 고속도로와 달리, 기존의 통일로는 자동차 전용 도로도 아닌 데다 차로도 너무 좁고 확장하기 어렵기 때문에 지금으로서는 그냥 그저 그런 시내 도로 내지 국도 레벨에 지나지 않는다. 하지만 임진각으로 가는 도로의 원조는 바로 이 길이었다는 점을 기억할 필요가 있다.

통일로의 고양시 북쪽 지점에는 '통일로 휴게소'라고 온갖 기념비들과 공원이 들어서 있고 공릉천이라는 하천도 가까이 있다. 본인은 북극 한파가 전국을 강타했던 새해의 첫 주말에는 거기를 다녀왔다.

사용자 삽입 이미지
사용자 삽입 이미지사용자 삽입 이미지

뭐, 휴게소라고 해서 고속도로 휴게소처럼 바로 근처에 식당이나 가게들이 들어선 건 아니고.. 그냥 공터 광장과 공원 정도만이 꾸며져 있었다.

사용자 삽입 이미지사용자 삽입 이미지

새마을 운동이니, 서울 올림픽이니 하는 왕창 옛날 냄새가 진동하는 기념석들..

사용자 삽입 이미지

아무나 들어가서 올라갈 수 있는 정자 같은 게 아니어서 아쉽다. 자유롭게 개방된 2층 정자라면 올림픽대로에 있는 청담 도로 공원 같은 느낌도 났을 텐데 말이다.

사용자 삽입 이미지사용자 삽입 이미지

그리고 이 '휴게소'의 길 건너편에는 6· 25 사변 필리핀군 참전 기념비가 세워져 있었다.
기념비에 새겨진 문구에 따르면, 필리핀군은 488명이 참전했으며, 이 기념비는 1974년 10월 2일에 건립됐다고 한다.

사용자 삽입 이미지사용자 삽입 이미지

필리핀군 기념비의 옆에는 고양시 출신 인물 중에 6· 25 참전 용사를 기리는 기념비가 있었다.
작년에 칠곡 왜관에서 봤던 애국 동산이 떠오른다. 거기서도 자기 지역 출신의 6· 25 참전 용사들을 잔뜩 기리고 있었으니 말이다.

안보 관광을 많이 다니고 나니, 과거에 비슷한 부류의 기념물을 봤던 것이 서로 연계가 될 지경이다.
이 기념비는 2004년 7월 27일에 여기 말고 다른 곳에 처음으로 만들어졌다가 2011년 1월 4일부로 이곳으로 옮겨졌다고 한다.

통일로라는 이름에 걸맞게 이런 볼거리도 있는 게 인상적이었다. 그런데 통일로라는 이름의 도로는 경상북도 경주에도 있다.
신라의 삼국 통일을 남북 통일 염원과도 오마주한다는 취지로 1977년엔 경주 남산의 동쪽 기슭에 통일전이라는 기념비가 건립됐기 때문이다. 통일전 근처의 도로 이름이 통일로이며, 심지어 '통일전 휴게소'도 있다.

내가 보기에 경주시는 박통 시절부터 관광 도시로서 특별 지원 대상으로 지정되어 혜택을 아주 많이 받았다. 1968년 12월에 국립공원 지정, 1974년에 보문 관광단지 개발, 통금에서 진작부터 열외, 호화 귀족 열차이던 새마을호 정차 따위 말이다. 게다가 도시형 국립공원이라는 건 현재까지도 경주시가 전국에서 유일하다.

끝으로.. 통일로라는 길이 닦이던 그 시절에 결의됐던 7· 4 성명이라는 건.. 우리나라가 영원히 으르렁대면서 적대할 것 같던 북괴하고도 그나마 “눈 가리고 아웅으로라도 좀 싸우지 말고 서로 평화적인 방법으로 통일을 모색해 보자~”라는 제스처를 취해 봤다는 것에 의미가 있다. (특히 1 21 김 신조 사태 때문에 서로 분위기가 얼마나 험악해져 있었던가?)

하지만 현실은 시궁창이고 통일은 개뿔.. 남북 지도자는 애초에 서로 온전히 신뢰 가능한 대상이 아니었다.
전근대 시절 옛날에 유럽에서는 귀족 장교들이 자국 졸병들보다 적국 장교를 더 신뢰할 정도였다고 하더라만(적이지만 최소한 약속을 어기지는 않는다) 20세기 후반의 한반도엔 그런 거 없었다.

그로부터 얼마 못 가 남한은 통일은커녕 자기 내부에서도 유신 독재(ㅋㅋ)가 시작되었고, 북괴 역시 특히 74년을 기점으로 주체사상과 함께 더욱 흑화하게 됐다. 쟤들도 겉으로는 통일 통일 거리면서 한쪽에서는 땅굴이나 파고, 공작원을 보내 남한 대통령을 암살까지 하려 했다. 그러니 통일은 더욱 물 건너가고 반공 분위기만 더 강해졌다.

2. 캠핑

통일로 휴게소를 방문하던 당시엔 서울의 낮 기온이 -10도 아래로 내려가는 강추위가 며칠 동안 전국을 강타하던 중이었다. 오죽했으면 최남단의 제주도까지 한파 경보가 내려졌으며, 한강이 얼고 황해 바다조차 일부 얼어서 양식업(...;; )과 비닐하우스 화훼업(치솟는 난방비)이 큰 피해를 호소했을 정도였다.

그래서 본인은 평범한 산 속이나 물가가 아니라, 이번엔 아예 얼어붙은 강 위에서 텐트 치고 자는 것도 가능하겠다는 생각을 했다. 당장 통일로 휴게소 부근부터 찾아봤다.

사용자 삽입 이미지사용자 삽입 이미지

오오.. 중앙까지 100% 언 건 아니지만 주변에는 물이 흐르다가 완벽하게 얼어 버린 곳이 있긴 했다.

사용자 삽입 이미지사용자 삽입 이미지

야호~! 주차장에서 그리 멀지 않으면서 텐트 치기 적합한 곳을 발견했다.
이불· 침낭 등 장비가 굉장히 많고 무거운 상태였기 때문에 도보 접근성도 무시할 수 없는 요소이다.;; 이것들을 오래 들고 다니니 팔과 허리가 뻐근했다.

사용자 삽입 이미지

해질녘에는 통일로 IC 부근의 상류로 자리를 옮겼다. 여기는 전구간이 꽁꽁 얼고 위에 눈까지 쌓였을 뿐만 아니라, 주변에 공원 같은 것도 없어서 인적이 더욱 없었다. 다만, 나 역시 강물 쪽으로 가기 위해서 갈대더미들을 타넘는 수고를 감수해야 했다.

사용자 삽입 이미지사용자 삽입 이미지

아아~ 세상에 이런 횡재가..
오도독오도독 눈 밟는 소리가 걸을 때가 아니라 누워서 몸 뒤척일 때 나는 그 느낌을 아시겠는가?
-15도도 이제 별 거 아닌 듯..^^ 아 그런데 다 좋은데 발은 좀 시렵다.. 이건 어쩔 수 없다..
믿음이 부족해서 강 중앙으로 더 가까이 가지 못했던 것이 아쉬울 뿐이다.

한숨 잘 잔 뒤 집으로 귀환했다.
그 당시엔 폰과 컴퓨터뿐만 아니라 차키의 버튼이 갑자기 먹히지 않기 시작했다. 키가 문제인지 차가 문제인지.. 차 문 못 열고 시동 못 걸면 어떡하나 깜짝 놀랐다. 키를 따뜻한 곳에 두니 다행히 다시 살아났다.

귀환할 때는 동부 간선 도로를 이용해 봤다.
의정부에서 서울 북부 구간이 싹 리모델링 돼서 확장되고 지하화가 된 걸 처음 봤는데.. 이게 딱 올해부터 개통한 거라고 한다. 신기했다.

사용자 삽입 이미지사용자 삽입 이미지

공릉천에서 야영을 한 뒤, 다음날 밤에는 중랑천 모처의 얼음판에서 또 야영을 했다.
여기는 공릉천보다도 얼음이 덜 생겨 있어서 중앙으로 접근할 수는 없었다. 하지만 텐트를 친 곳은 보다시피 명백하게 땅이 아니라 얼음이었다.

산천 어디서든 텐트만 치면 나만의 밀실이 생긴다는 게 좋다. 그리고 밖이 아무리 추워도 장비를 충분히 챙기면 체온 에어포켓으로 버틸 수 있다는 것도 좋다. 이렇게 잊지 못할 추억을 만들었다.

Posted by 사무엘

2021/01/29 08:35 2021/01/29 08:35
, , , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1848

« Previous : 1 : ... 41 : 42 : 43 : 44 : 45 : 46 : 47 : 48 : 49 : ... 215 : Next »

블로그 이미지

그런즉 이제 애호박, 단호박, 늙은호박 이 셋은 항상 있으나, 그 중에 제일은 늙은호박이니라.

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2024/05   »
      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
26 27 28 29 30 31  

Site Stats

Total hits:
2712256
Today:
332
Yesterday:
1589