2019년 4월 5일 금요일

인공지능이 인간에게 깨우쳐주는 것

인공지능에 대한 회의적 시각은 아직도 만연한데, 그건 인공지능에 대한 기술적으로 들어갈수록 더 그렇지 않나 싶다.
어차피 컴퓨터로 할 수 있는 연산이라는 것이 매우 제한적인 것이고, 그것들의 파생된 혹은 복잡하게 조합된 연산이라고 해 봐야 그 한계가 뻔해 보이기 때문일 수도 있다.

하지만 빅데이터, 데이터의 분류와 결합, 데이터의 검색과 변형, 딥러닝, 상황에 따른 유동적 확률의 적용 등이 엮어내서 도출되는 그 무언가가 과연 어떤 의미를 지니겠는가 하는 건 완전히 별개의 문제이다.

컴퓨터가 쉬지 않고 이 작업들을 기계적으로 반복하고 있다고 하더라도, 그 순간순간에 도출되는 중간 결과물들에 대한 의미의 판단마저 스스로 하지 못한다면, 막대한 리소스를 투입하고도 인간들이 얻을 수 있는 결과는 아무것도 없을 수 있다.

그렇다면 과연 컴퓨터가 스스로 어떤 의미를 파악하고 판단할 수 있겠는가?

바로 이 문제가 인공지능에 대한 의구심의 핵심이다.


알파고가 바둑에서 이기고 지는 것에 대해 대체 어떤 의미를 가지고 있을까?
이세돌이 졌을 때 느꼈던 패배감 좌절을 알 수 있을까?
그리고 한번 이겼을 때의 쾌감과 자신감을 알 수 있을까?
그건 그냥 감정이라고? 의미가 아닌?

자동 통역 시스템들은 자신들이 통역해야 할 문장의 의미를 알고는 있는걸까?
그래서 통역해낸 결과도 같은 의미를 가지고 있다는 걸 알고는 있는걸까?
그 결과를 다시 역변역했을 때, 최초의 문장과 조금이라도 달라졌다면 그게 어떤 차이인지 알고 있을까?
알리가 없지 않은가?


하지만 이와같은 인공지능에 대한 강한 의구심을 떨쳐낼 수 있는 개념은 따로 있다.

'그래서, 인간은 과연 정말 알고 있는건가?'

인간들이 알고 있다고 생각하는 것들이 정말 맞는것일까?
그냥 알고 있다고 생각하는 건 아닐까?
만약 신적인 존재, 전지적인 존재가 인간들의 지식을 보면 어떤 생각이 들까?
아주 단편적이고, 아주 제한적인 시간과 공간에서만 들어맞는 자기들만의 자식을 가지고 마치 절대 진리와 맞닿아 있을거라 우쭐거리는 존재?

그럼에도 불구하고, 인간의 과학기술이 현실세계에서 적용되고 효과를 보고 있다면, 컴퓨터의 인공지능 또한 제한적인 시간과 공간에서만이라도 그 나름대로의 효과가 있지 않겠는가?
인간의 지식이라는 것이 진리와 일치하지 않더라도 어떤 효과를 가지고 나름의 발전을 해 왔다면, 인공지능이 습득한 그 무언가도 나름대로의 효과를 가질 수 있지 않겠는가 말이다.(설령 인간이 보기에는 말도 안되거나 이해할 수 없다해도)


제목처럼, 인공지능의 한계가 뻔히도 보이지만, 그만큼 인간도 한계를 가지고 있다는 자기 반성의 기회를 주고 있다.
그리고 인공지능에 새로운 기대를 걸 수 있는 이유는, 인간이 스스로도 틀릴 수 있다는 겸허함 마음을 가진 토대에서만 가능한 일이 아닐까 싶다.

2019년 3월 21일 목요일

인간의 언어(Human Languages)

통상적으로 인간이 사용하는 언어를 자연언어 Natural Languages라고 부른다.
나와 같은 프로그래머는 프로그래밍 언어 Programming Languages와 구별하기 위한 이 표현을 그냥 편의상 받아들여서 사용하고 있다.

그런데 좀 우습지 않은가?
자연언어? Natural Languages?
마치 무언가 원초적인 힘을 가지고 있으며, 신성 불가침의 속성을 가지고 있다는 느낌을 주는 표현이 아닌가?


과거 자연언어 처리를 위한 방법으로 도입되었던 분석적 방법은 매우 제한적이거나 불완전한 면이 많았다.
어째서 이 방법에 문제가 많았던 것일까?
자연스럽게 인간의 언어를 이해하고 또 문장을 생성하기 위해서는 필요로 하는 문법이 너무나 많다고 할 수도 있다.
혹은 너무나 많은 예외 상황을 탓할 수도 있으며, 그나마도 어떤 예외를 적용할지 판단할 기준을 찾기가 너무 어렵다고도 할 수 있다.

사실은, 애초에 문법으로 배울 수 있는 언어는 아주 일부분이며, 단지 시작일 뿐이고, 수많은 예외 상황을 습득하는 것이 진짜 언어를 배우는 것이었기 때문일 것이다.

인간의 언어란, 아주 합리적이지도 않고, 이성적이지도 않다.
어쩌면 아주 오랜 시간을 거치면서 서로의 말이 제대로 전달될 수 있는 방법에 대해서 경험적으로 변형되어 온 것일지 모르겠다.

최근의 자연언어 처리는 빅데이터를 기반으로 하는 방법이 주로 사용되는 듯 하다.
그리고 이 방법의 문제도 많겠지만, 인간이 언어를 배우는 방법에 더 가까워 보인다.

그래야 일곱시 일곱분이 아닌 일곱시 칠분이라는 표현을 해석하고 생성할 수 있지 않겠는가.


잠깐 영어, 영어 공부에 대한 생각

한국인이 영어를 배우기 힘들어 하는 이유?
언어의 유사성이 매우 낮기 때문이 아닐까?
유사성이라함은 언어의 구조적인 유사성 뿐 아니라, 언어가 통용되는 사회 문화 철학적 유사성을 모두 함축하고 있다.

곰곰 생각해보면, 우리가 영어를 배우면서 종종 겪게되는 어려움은 이런거다.
"이러이러한 표현을 영어로 어떻게 말해야 하나요?"
그런데 간혹이긴 하지만, 이런 답변을 보게 된다.
"본토에서는 그런 식의 말을 쓰지 않는다. 그래도 굳이 영어로 표현하자면 ..."

이런 경우를 보면 정말 언어가 사고(思考)를 창조한다는 의미를 알게 된다.
언어로 표현할 수 없는(표현하지 않는) 것은 생각할 수도 없는 것이다.

유사성이 떨어지는 언어를 습득하기 위해서는 먼저 생각의 틀을 바꾸어야 한다.
한국인은 한국어로 생각을 하고 이걸 영어로 옮기려고 하지만, 이 경우에는 기존에 영어에서 쓰지 않던 새로운 표현 방식을 만들어 내야 한다.
그러니 외국인과의 대화에서 서로가 이해할 수 없어서 곤란해하는 경우가 속출하고 대화는 단절되고, 대화가 두려워지고, 관계는 서먹해지고...

원초적으로 따지면, 자신이 가지고 있던 모든 지식을 다 비우고, 영어가 사용되는 환경과 상황에서 생활하면서, 그곳에서 사용되는 표현 방식을 익히고 쓰면서 배워야 한다.
그런데 그게 가능하겠는가?
그렇다면 대안으로 외국인들이 사용하는 문장을 그냥 따라한다.
그 상황을 보면서 따라하고, 그 상황을 상상하면서 반복한다.
그렇게 한 문장 한 문장이 쌓이게 되면, 영어로 생각하는 영역과 한국어로 생각하는 영역이 다르다는 걸 알 수 있을 것이다.

애초에 이런 생각의 영역이 다를 거라는 생각은 없이, 언어가 단지 생각을 표현하는 수단이라고만 여겼기에 영어 공부는 틀렸던 거다.
언어는 생각을 표현하는 수단이기 이전에 생각을 만들어내는 도구다.
이 도구가 없다면 생각도 불가능하다.

한국어라는 도구가 만들어 내는 생각과, 영어라는 도구가 만들어 내는 생각은 아주 많이 다랐던 것이다.

2019년 2월 9일 토요일

malloc()의 구현 방법?

C 언어에서 흔하게 사용되는 메모리 할당 함수인 malloc()은 어떻게 구현되어 있을까?
함께 짝으로 사용되는 free()는 어떻게 구현되어 있을까?

흔하게 공룡책으로 불리우는 Operating System Concepts에서 배웠던 기억으로는 first-fit과 best-fit이라는 전략이 있다는... 어렴풋한 기억이 있을 뿐이다.
당시의 그 책은 매우 유용하기도 했지만, 다분히 교과서적이고 개념 위주였기에 실제 구현과는 거리가 좀 있었던 것으로 기억한다.

아무튼...
커다란 메모리 공간을 확보해서 힙으로 사용하도록 정한 후에, malloc()이라는 함수를 통해 메모리 할당 요청이 들어왔을 때, 그리고 메모리를 다 사용한 후에 free()라는 함수를 통해 메모리를 반납할 때, 이들을 어떤 식으로 처리하는 것이 좋을까?

우선은 잠시 생각해 본 아이디어를 끄적여 보겠다.

- 일단은 first-fit으로 구현.

- 메모리의 할당과 반납의 반복으로 힙은 여기 저기 조각난 상태가 될 것인데, 이 경우에 메모리 할당 요구가 발생하면, 비어있는 조각들 중에 크기가 맞는 것을 골라서 할당해 주어야 한다.
- 이를 위해 메모리 할당 테이블과 같은 별도의 정보를 관리하는 것도 하나의 방법이지만, 아주 작은 메모리의 할당이 많이 발생하면 관리를 위한 정보가 급격히 늘어나는 문제가 있다.
- 예전에 어떤 프로토콜 스택을 사용하면서 소스를 살펴보니, 이런 관리 정보를 힙 내부에 보관했던 기억이 있다. 즉, 사용하지 않은 힙의 메모리 내부에 비어있는 메모리 블럭들에 대한 정보를 저장하여 관리하는 것.
- 비어있는 메모리 블럭의 시작 부분에 블럭의 크기와 이전 블럭의 주소, 다음 블럭의 주소를 가지고 있는 구조. 최초의 힙은 블럭의 크기가 힙의 크기와 일치하고 이전 블럭의 주소와 다음 블럭의 주소는 null 값이 될 것이다. 전역 변수로 비어있는 첫번째 블럭의 주소만을 가지고 있으면 되고, 이 변수의 최초값은 힙의 시작 주소와 일치.
- 메모리 할당 요청이 들어오면 전역변수로 첫번째 빈 블럭부터 시작하여, 할당할수 있는 크기의 블럭이 나올 때까지 링크드 리스트처럼 연결된 블럭을 순회한다.
- 할당 가능한 블럭이 나오면, 할당 요청된 크기만큼을 할당하여 돌려주고, 블럭의 남은 조각을 새로운 블럭으로 리스트에 넣어주면 된다.

- 메모리 반납은 시작 주소만 있을 뿐, 크기는 없다. 위와같은 구조에서 해당 주소만이 주어졌을 때, 크기는 어떻게 알아내야 하는가?
- 할당된 메모리의 앞 부분에 할당된 블럭의 크기를 넣는다? --> 오케이.
- 그러면 비어있는 블럭의 맨 처음에도, 할당된 블럭의 맨 처음에도 그 블럭의 크기가 들어가는 셈.

- 메모리 얼라인먼트 문제?
- malloc()함수에서 할당 크기가 아니라, 메모리 단위와 개수로 할당을 받는 이유는 뭘까?

2019년 2월 7일 목요일

인공지능의 의미

인공지능은 한때, 흥미로운 SF의 소재였을 뿐 UFO나 외계인, 예티처럼 현실 세계에는 거의 아무런 영향을 끼치지 못하는 '꿈'의 기술이었다.

알파고의 출현은 가히 충격적이었다.
바둑이라는 게임에 한정된 것이었지만, 그 위력과 영향력에 대한 희망과 두려움은 전세계인에게 분명한 흔적을 남겼음에 틀림없다.
물론, 그 이후론 이렇다할 충격적인 인공지능의 출현이 보도되지 않아, 다시금 예전의 일상으로 돌아온 듯 하지만, 이제 우리의 생활이 큰 변화를 맞을 수 있다는 사실은 인정할 수 밖에 없어 보인다.

어쩌면 그렇게나 큰 충격은 다분히 우리가 생각하는 인공지능에 대한 무지에서 비롯된 것이 아닐까 싶다.
기계는 쉬지 않고 엄청난 속도로 학습하고 빠르게 진화할 수 있다고 생각하지만, 틀림없이 그건 아주 어려운 일이다.
마치 모든 분야에 속속들이 인공지능이 침투할것이라고 생각하겠지만, 그러기위해 필요한 자원(?)은 막대한 수준을 넘어 현재로썬 불가능할지도 모르는 수준일 것이다.

딥러닝, 빅데이터, 서칭 알고리즘, 데이터의 분류, 분산된 데이터의 적절한 결합, 이를 바탕으로 한 새로운 추론 등등...
각 기술의 작동 방식을 이해하기도 어렵지만, 이해한다 해도 어떤 데이터가 수집되어 있는지에 따라 결과는 큰 차이를 보일 것이기에, 인공지능 기술이 어떤 결과를 가져 올지는 예측하기 쉽지는 않다.

즉, 인공지능이 인간의 생활을 근본부터 바꾸리라는 희망이자 두려움에 대해서는 약간 냉정함을 가질 필요는 있어보인다.
상상처럼 '완벽한' 인공지능, 광범위한 영역에 단일한 메커니즘으로 운영되는 그런 인공지능은 여전히 '꿈'의 기술인 듯 하기 때문이다.


오히려, 인공지능에 대한 기대감과 시각을 바꿀 필요가 있어 보인다.

아마도 인공지능의 발전은 기대만큼 빠르지 못하고, 많은 자원을 필요로 하기에 중간중간 그 효용성에 대한 의문이 제기될 소지가 많다.
그럼에도 불구하고 꾸준히 발전시켜야할 분야라고 생각하는데, 그 이유는 이렇다.

수치나 논리로 설명을 하긴 어렵지만 직관적으로 이런 생각이 들곤 하는데,
가령 IQ가 80인 사람들이 제아무리 많이 모여도, 제아무리 많은 시간을 투자한다고 해도 아인슈타인의 상대성이론을 만들 수는 없겠다 싶은 생각.
물론 그 사람들이 모두 모여 덧셈 곱셈을 해 내는 속도는 이인슈타인보다 훨씬 빠르겠지만.

자칫, 타고난 지능에 대한 차별로 보일 수 있겠지만, 이건 오히려 그 반대의 상황이다.
즉, IQ가 80인 사람들이 아무리 노력하고 아무리 많이 모여도 이룰 수 없었던 수준에 도달하는 '방법'에 대한 얘기인 것이다.

과연 그런 방법이 존재할까?
만약 그 방법이 존재한다면, IQ 150인 사람이 IQ 200의 수준에 도달하는 방법도 찾을 수 있으며, 인간이 외계인 혹은 신의 수준에 도달하는 방법도 찾을 수 있을지 모른다.

인공지능은 바로 그 '방법'의 하나이다.
계산만 빠르게 하던 컴퓨터가 인간의 사고방식 수준에 도달하는 '방법'


사람은 개와 고양이를 구별할 수 있지만, 컴퓨터로는 그게 어려웠다고 한다.
사람들은 모두 언어를 구사하지만, 컴퓨터가 사람의 언어를 이해하는 건 아주 어려운 일이었다.
사실 그렇게 어려웠던 건, 사람들이 그런 능력을 공짜로 부여받았기에, 특별한 어려움 없이 습득한 능력이기에, 어떻게 그걸 하는 것인지 그들 자신도 그 '방법'을 모르고 있었던 것이다.

사실, 이제는 컴퓨터가 고양이와 개를 구별할 수 있다고 한다. 인간의 언어를 이해하고 명령대로 이행하고 번역이나 통역도 한다고 한다.
그게 단지 빅데이터를 통해 단순히 비교 검색하는 것으로 이루어지는, 컴퓨터의 인간 '흉내내기'에 불과한 것이 아닐까 생각하지만, 우리들 스스로도 우리가 어떻게 구별하고 어떻게 이해하고 있는지 모르는데, 컴퓨터의 그것을 비난할 수 있겠는가.

2018년 11월 16일 금요일

컴퓨터의 이상한 증상 - 고장의 과정?

글을 시작하기 전에 몇가지 핵심적인 단어를 포함하는, 간단한 문장의 결론부터 밝히고 시작을 하겠다.


* 오래된 컴퓨터에서 하드디스크에 이상이 발생하기 시작했다.
 - 하드디스크의 속도가 현저히 느려지기 시작한 것.
 - 이대로 두면 하드디스크의 데이터를 모두 잃게 되리라 생각했고
 - 새 하드디스크를 구입해서 새 OS를 설치했다. (Windows 7)
* 그리고 사용한지 2달 정도 되었다.
* 사용 중에 네트워크가 끊기는 현상이 가끔 발생하더니 빈도가 차츰 많아졌다.
* 이벤트 뷰어를 보니 네트워크 칩의 오류가 기록되어 이었다.
* 뿐만 아니라 디스크 콘트롤러에서도 오류가 발생하는 것을 확인했다.
* 디스크 포트를 변경하는 것으로 문제가 상당히 완화 되었다.
* 하지만 여전히 발생한다.
* 혹시나 Windows 7의 문제일까 의심했다.
 - 그리고 새 하드디스크의 성능을 시험하고, 맛이 가려던 하드디스크를 함께 시험했다.
 - 문제는 SATA 포트에 있었고 하드디스크에는 문제가 없었다.
* 예전의 하드디스크, 예전의 OS (Windows XP), 단지 SATA 포트만 바꾸어 옛날로 돌아갔다.
* 예전의 상황에서도 네트워크 끊어짐의 현상이 발생했다.
 - 주로 비디오와 네트워크를 동시에 사용하는 경우에 주로 발생했다.
 - 보드에 내장된 네트워크를 disable 시키고, 오래된 PCI 네트워크 카드를 설치했다.
* 또 다시 하드디스크의 속도가 느려졌다.
 - 보드에는 4개의 SATA 포트가 있다. 4개중 2개가 이상해졌고, 그 2개가 모두 Master에 해당하는 포트였다.
 - 될까 싶었지만 Slave 포트에 연결했는데, 다행히 잘 부팅했다.
* 오디오에서 이상한 현상이 나타났다.
 - 처음 오디오가 켜질 때에 스피커에서 딱~ 하는 큰 소리가 났다.
 - 마치 갑자기 쇼트된 것처럼.
* 얼마간 잘 쓰다가 다시 하드디스크의 속도가 느려졌다.
 - 마지막 남은 SATA 포트에 연결했다.
* 갑자기 블루스크린 발생
 - 며칠간의 간격으로 발생한 듯 하며, 간격이 점차 줄어든다는 느낌.
 - 주로 크롬브라우저에서 동영상(유튜브 혹은 기타 동영상)을 보는 중에 많이 발생했으며,
 - 마지막은 크롬 브라우저로 일반 사이트를 접속해서 사용하던 중, 그 사이트의 다른 페이지로 링크를 타고 넘어가는 순간... 한동안 응답이 없고, 브라우저 하단에는 "캐시를 기다리는 중"이라는 메시지가 보이다가 블루스크린이 떴다.
 - 이 현상이 발생할 때면, 하드디스크의 작동 LED는 들어와 있으나 메모리 덤프가 끝나지 않아 블루스크린 상태를 계속 유지하고 있으므로 강제로 파워를 꺼야만 했고,
 - 다시 새로 시작한 후에는 항상 Event Log에 디스크 콘트롤러 오류, 디스크 읽는 중 패리티 오류, 디스크 에러 등의 이벤트가 발생했었다고 나온다.


이상의 문제 현상들이 나타났을 때, 문제의 원인들을 찾아 보려고 노력했는데 아직까지도 정확한 원인은 찾을 수가 없었다.

1. 하드디스크의 노후
  - 이 부분은 원인이 아니었음이 밝혀졌다.
  - 새 디스크로 바꾼 후에도 문제가 타나났고, 노후된 하드 디스크로도 포트만 바꾸어서 정상이 되었다.

2. 파워의 부족
  - 위의 과정에서 중간 즈음에 이 문제를 의심해 보았다.
  - 본격적으로 의심한건 마지막 블루스크린이 뜨는 때 부터였다.
  - 블루 스크린이 발생하고 바로 다음날 파워를 뜯어서 분해해 보았지만 아무 문제도 찾지 못했다.
  - 사실 파워서플라이의 파워 부족을 어떻게 찾아내는지 그 방법도 모호했다.
  - 현대 내가 가지고 있는 멀티미터로는 12V/5V의 전원 핀에서 정상적인 전압이 나오는지 확인해 보는 것 뿐인데, 현재의 파워는 물론이고, 예전에 쓰다가 고장났다고 생각했던 파워도 전압 자체는 정상으로 나오고 있음을 확인했다.
  - 파워는 전압은 물론이고, 충분한 전류도 공급이 되어야 하지만, 전류를 측정하는 건 만만치 않은 작업이다.

3. 보드의 문제
 - 네트워크가 끊어지는 문제를 처음 본 다음부터 이 문제를 의심했다.
 - 육안으로 확인해 본 결과로는 부풀어오른 콘덴서 한개가 보였는데, 인터넷으로 구한 이 메인보드의 회로도를 통해서 확인해 보니 이 콘덴서는 전혀 상관이 없는 IEEE 1394에만 사용되는 콘덴서였다.
 - SATA 포트가 돌아가면서 문제를 일으켰으니 이 부분을 확인해 보았지만, 포트와 포트 주변의 회로는 매우 간단했으며 문제를 찾을 수 없었다.
 - SATA 포트가 연결되는 곳은 사우스 브릿지인 ICH7 칩인데, 이 칩의 주변에서도 특별한 문제점을 찾을 수 없었다.
 - 네트워크의 문제점이 발생하는 경우가 대부분 비디오와 함께 사용하는 경우였던 점을 생각하면 노스브릿지도 생각해 볼 수 있다. 하지만 이 칩의 주변에도 문제는 없어 보였다.
 - 결국 문제는 있지만 원인은 발견할 수 없다는 것.
 - 하지만 여기에서 한가지 의심스러운 정황은 IEEE 1394와 관련된 콘덴서가 부풀은 점.
 - 사용하지도 않았던 저 콘덴서는 왜 부풀은 것일까? 내가 구한 회로도가 잘못된 것이고, 실제로는 영향이 있는게 아닐까? 아니면 저 콘덴서를 부풀게 만든 어떤 원인이 다른 부분에까지 영향을 끼쳐서 문제가 된 건 아닐까?


지금으로썬 할 수 있는 방법이,
1. IEEE 1394에서 사용된다고 생각했던 콘덴서의 교체.
2. Video Card의 교체
3. 파워서플라이 교체
의 정도가 아닐까 싶다.

아니면... 이제는 놔줘야 하는걸까.

CPU : Intel Pentium D 920 Presler
Memory : DDR2 6400 1G x 4 (Dual Channel)
Main B'd : Gigabyte (GA-8i945PMF)
Video Card : NVidia GeForce 9500GT 512M
HDD : Hitach 1TB (HDS721010CLA332)

2018년 9월 16일 일요일

지구 종말에 대비해 소수를 선발하는 알고리즘?

곧 추석이 다가온다고 그러는지, 주말에 공중파 방송에서 외화들을 방영했다.
대단한 신작은 아니고 개봉한지 한참을 지난 영화지만...딥 임팩트라는 재난 영화였다.

지구로 돌진하는 소행성을 맞이하여 고군분투...그러나 역부족... 극소수만이 방주로 피신하고 대다수는 포기해야만 하는 암울한 종말.

이 영화에서는 무작위 혹은 인류에게 꼭 필요한 인재들을 선발하여 피신시킨다는 대목이 나오는데, 비슷한 재난 영화로 2012에서는 거금의 기부를 한 재벌들과 소수의 꼭 필요한 인재들을 선발해서 방주에 승선하는 대목이 나온다.


과연, 정말로 이런 상황이 닥친다면, 어떤 사람을 어떤 식으로 선발해야 하는 걸까 하는 고민을 해 보았다.

좀 극단적인 경우를 가정해서, 지구가 아닌 다른 행성으로의 이주를 하는 경우라면?

아주 대략적으로만 알고 있고, 세세한 부분은 알지 못하며, 어떤 상황이 닥칠지 예측이 불가능한 그런 곳에서 인류가 충분히 생존하기 위해서는 무엇이 필요할까?


다윈의 진화론을 인정한다면, 인류 진화의 방향은 사방 팔방 모든 방향으로 뻗쳐 나간다는 것을 인정해야 한다.
인간은 큰 키와 작은 키, 큰 몸집과 작은 몸집, 큰 용량의 뇌와 작은 용량의 뇌, 어떤 것도 치우치지 않는다.
진화의 방향은 "다양함"에 있다.
그 다양함은 전체 인간 종족의 입장에서는 환경에 대한 적응의 확률을 높이기 때문이다.


미지의 세계로의 이주를 위해서는, 가능한 다양한 분포를 이루도록 선발해야 할 필요가 있다.
어떤 요소를 대상으로 할 것인가가 실제로는 매우 중요한 요소가 되겠지만, 이것이 일단 정해졌다고 가정을 하자.
아마도 특정 요소를 기준으로 사람들의 분포를 모두 조사하면 가우시안 분포를 보일 것이다.
하지만, 이건 지구라는 환경에 적응한 결과일 뿐이다. 새로운 세상에서는 중심 축이 이동할 가능성은 얼마든지 있으며 이 또한 예측 불가능하다.


자, N개의 평가 요소가 주어졌다.
선발 대상으로 주어진 사람은 모두 M이라고 하자.

이제 M명의 사람들에 대해서 N개의 평가 요소에 대한 일종의 점수가 모두 매겨져 있다면,
과연 어떤 방법으로 선발을 하는 것이 가장 고른 분포를 이루게 할 것인지,
또 대단히 큰 수의 M명에 대해서 어떻게 효율적으로 빠르게 이 계산을 끝낼 수 있을까?
(단, 각 평가 요소는 서로에 대해 독립적이라고 가정한다.)

2018년 8월 23일 목요일

카카오톡 친구 차단에 대한 진실?

카카오톡을 아주 최근에야 설치하게 되었다.(바로 이틀 전이다.)

지금까지 카카오톡을 설치하지 않았던 이유는,
 - 주소록에 있는 사람들이 자동으로 친구로 등록된다는 문제.
 - 나의 근황을 알리고 싶지 않은 사람도 있고, 그런 사람들에게 관심을 일으키고 싶지도 않었다.
 - 개인적으로 사람들과의 교류는 적정한 거리가 필요하다는 평소의 생각도 한몫. 너무나 쉬운 연결 통로는 나의 개인적인 시간과 여유를 침범할 것이 자명하기 때문이었다.


그럼에도 불구하고 카카오톡을 설치한 이유는,
 - 몇몇이 함께 만나는 모임에서 약속 시간과 장소를 정하기 위해서 누군가 문자메시지를 모두에게 중복해서 발송해야 하고, 또 다른 사람의 의견이나 사정을 나머지 인원에게 재전송해야 하는 어려움을 겪고 있었다. 그래서 모두가 한번에 모여 얘기할 단톡방이나 채팅 공간이 필요했다.
 - 처음에는 녹색창 회사의 밴드를 쓰려 했는데, 누군가가 안쓴다고 해서, 결국은 모두가 쓴다는(나를 제외하고) 카카오톡을 선택.
 - 위에서 내가 우려했던 문제들은 적절한 설정을 통해서 방지할 수 있다는 친구의 설명을 들었다.



인터넷에서 검색을 해 보니, 실제로 카카오톡의 설정에서 "자동 친구 추가"를 해제함으로써 내가 우려했던 문제들이 해결된다는 글들이 여럿 보였다.

그리고, 용기를 내어 카카오톡을 설치하고, 본인 인증도 하고, "자동 친구 추구"나 "친구 추천"등의 설정을 모두 막아놓고 일단락.

모임의 친구들은 다음날 추가하려고 생각하고 잠이 들었다.



다음 날, 가족들이 만든 단톡방을 틍해서 누이가 톡을 보내왔다. 드디어 가입했구나, 축하한다, 어서 와라.... 허걱

인사도 뒤로 미루고, 대체 어떻게 알게 된건지 추궁하자 아버지의 스맛폰에 내가 친구로 올라왔다는 것. 그걸 보고 누이도 확인하고 톡을 보내왔다는 것.

대체 무슨일이 벌어진걸까?

잠시후에는 더 놀라운 일들이 벌어졌는데, 내 주소록에 있는 사람들 중 대다수가 친구로 올라왔다는 것. 나는 황급하게 가족과 몇몇의 친구들을 제외하고는 모든 친구들을 일일이 차단했고, 프로파일 비공개까지 설정을 해 줘야 했다.



가족들 모두 톡을 나누는 동안 카카오톡의 고객센터 항목에서 문의하기에 장문의 글을 올렸다.
그리고 다음날에야 답변이 올라왔다.


내가 올린 질문의 요지는, "나는 자동으로 친구가 추가되는 것을 원하지 않아서 모든 설정에 이와 관련된 것들을 모두 해제해 두었다. 그런데 원치 않는 상대방에게는 내가 친구로 보여졌다. 대체 무엇이 잘못된 것인가? 내가 설정을 잘 못한 것이 있는가?"

그리고 답변의 요지는, "카카오톡은 주소록에 저장된 번호의 사람이 카카오톡에 가입하면 친구로 등록되는 것이 기본 메커니즘이다. 따라서 니가 설정을 어떻게 하든지, 누군가 주소록에 너를 등록해 두었다면 그 사람에겐 니가 친구로 나타난다."라는 거....ㅆㅂ



그리고 더더욱 반가운(?) 사실은, 일단 상대방에게 친구로 나타나면, 니가 뭘 어떻게 하든지 상대방의 친국 목록에서 뺄 수 있는 방법은 없다는 거... 푸하하핳ㅎㅎㅎㅎㅎㅎㅎㅎㅎ


모두가 이런 사실을 알고 있는걸까?
아마 사용하고 있는 사람이라면 누구나 다 알고 있을 듯도 하지만,
아직 사용하지 않고 있는 사람이라면, 인터넷에 떠도는 그런 낭설을 믿고 안심해서 가입했다가 낭패를 보는 일은 없었으면 한다.

카카오가 프라이버시라는 단어의 의미를 알고는 있는 걸까?

2018년 7월 10일 화요일

하드 디스크 드라이브의 노후

과연 하드디스크 드라이브는 얼마나 오랜시간을 사용할 수 있을까?

지금까지 사용했던 수많은 하드디스크드라이브는 대부분 어느 시점엔 폐기었는데,
초창기에는 하드디스크 드라이브의 인터페이스의 변화에 따라 새로운 시스템에 사용이 불가능해지거나, O/S의 변화와 기술의 변화에 따라 필요로 하는 용량이 극적으로 늘어나면서 폐기되기도 했다.

물론 사용 중에 고장으로 인해 페기된 경우도 많았는데, 대부분은 IDE interface 방식으로 어느 순간에 갑자기 시스템에서 하드디스크를 인식하지 못하게 되거나, "딸깍,- 딸깍-..."하는 소리를 내면서 정상적으로 데이터를 읽고 쓰지 못하게 되면서 O/S 부팅이 되지 않게되곤 한다.
(전문적인 지식이 없지만, 나름대로 짐작하기에는 하드디스크의 뒷면에 부착되어 있는 interface B'd에 문제가 생겨서 고장난 것으로 생각된다.
즉, 물리적인 디스크와 헤드는 정상이므로, 이 Board만 수리하거나 같은 모델로 교체하면 정상적으로 작동하지 않을까 싶기는 하다.)


2018년 7월 11일 현재 사용하고 있는 컴퓨터 시스템도 꽤 오래된 구닥다리이지만, 여기에 장착해서 사용하고 있는 하드디스크도 굉장히 오래되었는데, 중간에 한번 교체한 것이긴 하지만 한번도 문제 없이 지금까지 사용하고 있다.(언제부터 쓴거지?)

그런데 며칠 전부터 컴퓨터가 이상하게 느려지기 시작했다.

항상 프로세스들에 대해 주시를 하고 있었는데, 특별히 이상한 프로세스도 없었다.
물론 안티 바이러스 프로그램은 사용하지 않는다.

그러다 발견하게 된 이상한 현상은,


컴퓨터가 느려진다 생각될 때에, Hardware Interrupts and DPCs가 CPU를 대부분 점유하고 있는 것을 알게 되었다.


그리고 혹시나 하는 생각에 하드디스크에 문제가 있는 것이 아닌가 싶어 확인을 해 보았다.
사용한 프로그램은 HD Tune.

HDTune Benchmark

전송 송도가 정상의 1/30에도 미치지 못한다.
인터넷을 찾아보니 이 모델의 평균 전송 속도는 대략 100MB/sec 전후.
Access Time은 거의 정상.
그리고 하드디스크가 자신의 일을 잘 못할 뿐 아니라, 이로 인해 컴퓨터가 전반적으로 느려지는 지대한 공헌(?)을 했다는 증거인 CPU Usage는 무려 55.8%.
아마도 정상이라면 2~4%를 넘지는 않았어야 하는 항목이다.

HD Tune의 나머지 항목도 살펴 보았다.

HDTune Info
HDTune Health

보통 하드디스크에 문제가 발생하면,
위의 항목 중 (05) Reallocated Sector Count가 증가하기 시작한다.
확실하진 않지만 아마 (C4) Reallocated Event Count도 같이 증가하지 않을까 싶다.
내 디스크의 경우에는 (C7) Ultra DMA CRC Error Count가 1146이 나왔다는게 의심스러웠는데 며칠간 추적해 봐도 더 이상 늘어나지는 않았다.

문득 이걸 보면서 들었던 생각은... 참 많이 썼구나... 였다.
(09) Power on Hours Count : 작동 시간이 30728시간. 3.5년간 하루 24시간 계속 사용해야 하는 시간이다.
(0C) Power Cycle Count : 껐다가 켠 횟수 5205회. 하루 한번씩만 컸다 켜도 14년이 걸리는 횟수.

HDTune Error Scan
시간이 너무 많이 걸리고, 상태도 메롱이라 Quick Scan으로 검사해본 결과는 이상이 없다.


인터페이스 보드에 문제가 생겨서 인식 불량, 데이터 접근 불가능의 문제가 생기는 경우는 종종 봐왔지만, 마치 사람이 늙어서 기운이 떨어지는 것처럼 하드디스크가 성능이 급격히 느려지는 경우는 처음이었다.

사실 이에 대해서 다른 의심을 해 보기도 했다.
여름이 되면 온도가 상승하면서 컴퓨터의 여러 부품들에도 열이 가해져서 데미지를 입는 경우가 있다.
혹시 파워서플라이에 문제가 있어서 적정한 전압이 공급되지 않거나 전력이 부족해서 생긴 현상은 아닐까 하는 의심.
전력의 문제는 모르겠으나, 직접 확인해 보니 전압은 정상적으로 공급되고 있었다.


언제 갑자기 동작을 멈춘다해도 이상하지 않을 상황이라, 새로운 하드디스크를 주문해 놓은 상태이다.

이제는 편히 쉬도록 해 주어야 하는 걸까?

2018년 1월 16일 화요일

Android 에뮬레이터?

Google에서 제공하는 Android SDK에 포함된 Android 에뮬레이터는 매우 무겁고 느리게 느껴진다.

Android 버전에 따라, Host의 시스템 성능에 따라 많이 달라지기야 하겠지만...

개발자의 입장에서는 실제 Android 기기와 100% 동일하게 작동하는 에뮬레이터가 가장 이상적이겠지만, 나처럼 특정 App을 PC에서 사용해야 하는 사용자의 입장이라면 완벽한 호환성은 양보하더라도 무난하게 사용할 수 있는 성능도 중요하다.

아마, 언젠가 이런 필요성 때문에 Android 에뮬레이터를 알아보긴 했었나보다.
그리고 언제나처럼 귀차니즘으로 "알아보기"만 하고 마무리는 짓지 못했었던 듯...

다시 필요성이 느껴져 잠시 고민을 하다가,
Android-x86이라는 것이 있음을 알게 되었다.
Virtualbox에 Android-x86을 설치하면 꽤 무난한 성능을 보여주길 기대하면서...

설치하는 방법은
https://www.howtogeek.com/164570/how-to-install-android-in-virtualbox/

Android-x86의 ISO를 다운로드 하는데 시간이 꽤 걸린다.
600~700MB 정도인데, 서버가 그리 넉넉하지는 않은 것인지 1시간 넘게 걸려야 다운로드가 완료될 예정.
기다리는 동안에 간략하게 포스팅 하는 중.

모쪼록, 다운로드 후에 귀찮다고 내버려 두지 않길 바란다.


다행히도, 다운로드 후에 설치도 해 보았고 몇가지 작동도 해 보았다.
우선 몇가지 팁(?)을 적어야 겠다.

  • 반드시 Virtualbox의 "마우스 통합 비활성화"를 선택해야만 한다.
    Virtualbox 메뉴의 "머신" 항목에 있으며 단축키는 Host(우측 컨트롤키) + i로 토글된다.
    이걸 선택해야만 하는 이유는, 터치하지 않은 상태에서도 마우스의 움직임을 볼 수 있기 때문인데.... 잘 이해가 안되면 직접해 보면 알게 된다.
  • 시스템을 종료할 때에는 Virtualbox 메뉴 "머신 - ACPI종료"를 선택하면 된다.
    핫키는 Host + h
  • 간혹 일부 앱의 경우에는 화면의 비율 때문에 90′ 회전하는 경우가 있다.
    앱의 종료 후에도 회전한 상태로 남아 있는 경우에는 메뉴 "머신 - Ctrl-Alt-Del누르기"로 원래 상태로 돌아 올 수 있다.

사용해 본 소감을 말 하면,
  • 많은 리소스와 메모리가 필요하다. 어쩌면 너무 당연한걸지도 모르지만, 스마트폰에 사용되는 CPU가 비록 모바일용 CPU라 할지라도 최신 사양인걸 생각하면...
  • 설치하는 중에 잠깐 먹통인 듯 싶은 경우가 있는데, 참고 기다리면 된다.
    디스크 파티션을 만드는 첫번째 화면에서 이런 경우가 있었다.
  • 설치 도중에, 정확히 말하면 파티션과 파일 시스템에 대한 설정을 모두 마치고 파일을 복사하는 과정에서 오류가 나서 멈춘 경우가 있다.
    다시 처음부터 시작하니 문제 없이 진행이 되었다.

위 링크의 마지막 부분에는 이 방법이 제일 효율적이지는 않다며 블루스택이라는 제품을 권유하고 있었다.... 이걸 왜 다 하고 난 다음에야 봤을까ㅠㅠ

2017년 7월 18일 화요일

wuaueng.dll ___ 0

사용 환경 : Windows XP SP3
CPU : Intel Pentium-D

문제의 증상 :

  • 최근 1~2년 사이에 발견한 것으로, 아이들(Idle) 상태의 CPU의 점유율이 50% 이상을 유지함.
  • 해당 프로세스는 svchost.exe였으며, 같은 이름의 프로세스 여러개가 동시에 존재하지만, 그 가운데 하나만 CPU 50%를 독점하고 있었음.
  • 해당 프로세스(svchost.exe)는 Automatic Update, BITS, COM+ Event System 등의 서비스들을 관장하는 프로세스였음.(Process Explorer로 확인)
  • 해당 프로세스 thread가운데, 시작 주소(Start Address)가 wuaueng.dll+0xa4f42인 thread가 CPU를 독점하고 있었으며 매우 빠른 Context Switching이 일어나고 있었음.
  • 해당 thread를 suspend 시킬 수 있었으며, suspend된 후에는 CPU 점유율이 정상으로 돌아 옴.
  • 현재 사용 중인 wuaueng.dll은 2010년 8월 18일에 만들어졌으며, 버전은 7.6.7600.256, 설명은 Windows Update Agent로 되어 있음.
  • 이 현상은 Windows 자동 업데이트 설정과는 무관하게 발생하는 것으로 보임.

CPU를 점유한 svchost.exe

해당 svchost.exe의 설명

CPU를 점유하고 있는 thread

suspend 시키자 CPU 점유율이 없어진다.

해당 모듈의 등록 정보

해당 모듈의 버전

이에 관한 문제를 해결하기 위해서 MS의 support와 MSDN을 검색했지만, 문제에 대한 제기는 있어도 해결 방법에 대해서는 별 정보가 없었다.

우연히 한글로 된 블로거의 포스팅을 발견하였고, 이 문제를 해결해 보고 싶어서 그 과정을 기록하기로 했다.


Windows가 느려졌다?

최첨단의 기술을 필요로하는 게임을 하는 것도 아니다.

하던 업무의 목표가 상향되면서, 더 복잡하고 다양한 기능을 가진 S/W로 업그레이드 한 것도 아니다.

늘상 하던 일을 했고, 내가 원하는 목표치는 항상 같은 수준이었다.

그래서 매일 같은 프로그램을 사용하고, 매일 같은 작업을 반복하고 있다.

그런데, 왜 내 컴퓨터는 점점 느려지는 걸까?


대단한 통찰력의 컬럼을 쓰려는 게 아니다.

그동안 겪었던 몇가지 궁금증, 발견한 몇가지 사실, 그리고 밝히고 싶은 몇가지가 있어서이다.


궁금증에 대한 한가지 설명(?)

- 매일 같은 브라우저를 열어서 같은 사이트를 돌아다니는데, 어느날 부터인가 부쩍 느려지고 버벅대는 컴퓨터. 대체 무엇때문일까?

:
(1) 나도 모르게 브라우저는 조금씩 조금씩 업데이트를 하면서 버그도 고치고, 새로운 사양의 기술도 추가해 나간다. 그러면서 조금씩 무거워지고 느려진다.
(2) 새로운 사양의 기술은 조만간에 여러 웹사이트에서도 적용된다. 아니 대부분의 웹사이트는 새로운 기술이 아니더라도, 자체의 룩앤필(Look & Feel)을 바꾸기도 하고, 내용을 바꾸면서 웹사이트 자체가 무거워지기도 한다.(사실 이게 대부분...)
(3) 흔하게 듣는 해결법에 해당하는 것으로, 인터넷 페이지의 방문 기록, 임시 파일, 캐쉬 파일 등등이 너무 많아져서 저장 매체의 처리가 느려지기 때문에 발생하는 문제도 있다. 이 경우에는 브라우저의 설정 등에서 쓸모없는 파일들을 지워주면 된다.


발견한 몇가지 원인들

- 구글 크롬 브라우저의 백그라운드 프로세스 문제
: 구글의 설정에서 선택할 수 있다.
 브라우저를 종료했음에도 불구하고 컴퓨터가 느리다면 한번쯤 확인해 봄직하다.
 크롬 브라우저가 워낙에 자주 업데이트되다 보니 어렵지 않게 부딪히는 문제인데, 백그라운드 상태에서 업데이트를 하느라 CPU와 Network, Disk를 상당 부분 점유하곤 하는데, 처음에는 이유를 몰라서 당황하다가 이유를 알고나서 괘씸해서 설정을 바꾸어 버리게 된다.

- LoL의 백그라운드 업데이트 문제.
: League of Legend도 크롬과 마찬가지인데, LoL의 경우에는 이를 사용자의 마음대로 바꿀 설정이 없다는 것. 보통은 게임을 다 마치고 난 뒤에 컴퓨터가 현저하게 느려지곤 하는데, LoL의 업데이트는 용량이 매우 크고 CPU를 많이 사용하는 듯이 보여서 체감상의 성능 저하가 크게 느껴진다.



밝히고 싶은 몇가지

- 특정 svchost.exe가 CPU를 독점하는 문제 (wuaueng.dll의 문제)
- nossvc.exe

2017년 1월 25일 수요일

키보드 후킹

MS-Windows 환경에서 키보드를 후킹하는 방법에 대한 프로그래밍 예 입니다.

http://www.codeguru.com/cpp/w-p/system/keyboard/article.php/c5699/Hooking-the-Keyboard.htm

반(反) 역공학 방지 기법?

Reverse Engineering Protection Technique = 역공학 방지 기법
Anti Reverse Engineering Technique = 반 역공학 기법

이 정도로 해석하고 이해하면 좋을 듯 한데,

Anti Reverse Engineering Protection Technique은 대체 뭐라고 해석하고 이해해야 하는 걸까?

반 역공학 방지 기법?

그렇다면 역공학 방지 기법을 무력화시키는 기법이라는 뜻인걸까?

그렇다면 다음 구문은...

Anti Reverse Engineering Protection Technique To Use Before Releasing Software
(원문에서 사용한 대문자를 그대로 사용한 것임)

'소프트웨어를 출시하기 전에 적용해야 하는 반 역공학 방지 기법'???

통상적인 소프트웨어라면, 역공학 기법에 의해 위변조 되어 악용되거나 핵심적인 기법이 노출되는 것을 방지할 필요성이 있을 수 있지만, 반 역공학 방지 기법이 필요한 소프트웨어란 대체 무엇일까?

암튼, 해당 사이트의 URL은 다음과 같다.
https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software

================================================================
※ 오랫만에 위 링크를 다시 방문해 보니 페이지의 타이틀이 바뀌었다.
Anti Debugging Protection Techniques With Examples.
'나처럼 이상하게 생각하는 사람이 많아서 정정했나 보군'이라고 잠시 생각했지만, 가만히 보니 이것도 별반 다를 것 없는 이상한 문장.
정확한 내용은 본문을 읽어 봐야 알듯. 그런데 아직도 안 읽어봤으면서 대체 언제 읽어 볼건데?

※ 이런 건 어떨까? 참고할 만한 링크 추가.
https://www.codeproject.com/Articles/30815/An-Anti-Reverse-Engineering-Guide
An Anti Reverse Engineering Guide
================================================================

2016년 3월 30일 수요일

파이썬의 라이브러리 NumPy + SciPy _____ 8

==========================================================
이 포스팅은 쓸모 없어진 포스팅입니다.
(NumPy + SciPy ____ 4 ~ NumPy + SciPy ____ 8)
해당 문제점은 Scipy 패키지를 빌드했던 툴(아마도 MS Visual Studio 201x)이 Windows XP를 지원하지 않아서 발생한 것으로 추측하고 있습니다.
이후의 포스팅에서 이 시행착오를 정리할 계획입니다. (아마도 NumPy + SciPy ____ 9)
==========================================================

어차피 우아하게 소스 레벨 디버깅도 물 건너간 상태다.

닥치고 수정 - 실행 , 재수정 - 실행의 무한 반복.

그나마 감 잡히는 부분이 있어서 다행이다.


로드하려는 라이브러리의 경로를 절대 경로로 지정하기 위해서 변환까지 하고, 변환하기 전의 경로를 사용한 부분.

dynload_win.c
pathname이라는 변수 대신에 pathbuf를 쓰는게 맞다고 생각해서 위 처럼 소스를 수정했다.

그리고 다시 빌드하고, 다시 실행해 본 결과,


역시나 같은 결과.

그것도 아니면 대체 뭐가 문제란 말인가?


dynload_win.c
의심이 가는 변수들의 값을 모두 확인하고자, 에러 메시지의 내용을 원하는 변수 값으로 출력하도록 수정했다.

그리고 다시 빌드하고 실행해 본 결과,


위의 함수가 호출될 때, 로드하라고 지정한 라이브러리는 _ufuncs
여기에 경로가 모두 포함된 pathname과 pthbuf는 결과적으로 _ufuncs.pyd를 똑같이 지정하고 있었다.


하지만 내가 알아낸 바에 의하면 _ufuncs.pyd라는 파일 자체를 로드하지 못한 것이 아니라, _ufuncs.pyd에서 필요로 하는 또 다른 DLL인 libifcoremd.dll을 찾지 못했기 때문에 발생한 것이었다.

그리고, 내 짐작엔 소스에서 로드하려고 LoadLibraryEx를 호출하는 이 부분이 바로 libifcoremd.dll를 대상으로 삼고 있을거라 생각했던 것이다.

하지만 그게 아니었다.

어쩌면 당연한거였는지도 모르겠다.

너무나 1차원적으로, 단순하게 생각했던 것이다.

저 메시지로 짐작하건데, _ufuncs.pyd도 라이브러리 이므로 LoadLibraryEx() 함수를 이용해 로딩하는 게 맞지만, OS의 입장에서 본다면, _ufuncs.pyd에서 또 다른 라이브러리의 함수를 사용할 수도 있는 것이고 그렇다면 그에 해당하는 DLL도 또한 로드해야만 제대로 된 작동을 할 수 있을 것이다.

그것이 libifcoremd.dll 이었던 것이다.

그렇다면 libifcoremd.dll은 어디에 명시되어 있을까?
아마도 _ufuncs.pyd에 명시되어 있을 것이다. 그래서 Ollydbg에서 해당 DLL을 찾을 수 없다고 메시지를 보여 줬던 것이리라.

그러면 통상의 DLL 탐색 순서에 따라 libifcoremd.dll을 탐색하고 찾아서 자동으로 로드해 주었으면 좋으련만, 윈도우즈에서는 그렇게까지 하지 않는 모양이다.

어쩌면 _ufuncs.pyd에는 libifcoremd.dll이 명시되어 있지 않을 수도 있고, 단지 libifcoremd.dll에 포함된 함수(프로시져)의 이름만을 명시하고 있을지도 모른다.

그렇다면 OS는 해당 함수를 가지고 있는 DLL이 무엇인지를 모두 뒤져봐야 할 것이고, 이건 너무나도 비효율적일테니, 특별히 자신이 가지 함수 이름을 미리 등록해 놓은 DLL에 대해서만 이런 서비스를 제공해 주는 것일지도 모른다.

(마침 _ufuncs.pyd에서 libifcoremd라는 문자열이 있는지 검색해 보았지만 찾지 못하고 있다. 오히려 Ollydbg가 메시지를 보여준게 신기할 따름.)

그렇다면 애초에 인텔의 이 라이브러리들을 아무 곳이나 PATH가 지정된 곳에 복사해 넣어서는 안되고, regsvr32라는 프로그램을 이용해서 등록해 주는 절차가 필요한 것이 아니었을까?

그렇다면 전에 받아 두었던 인텔의 배포용 라이브러리를 설치하는 것이 가장 좋은 해결책이 될지도 모르겠다.


그래서 당장 실행.
Intel C++ Redistributables for IA32

Intel Fortran Redistributables for IA32

설치 후에 추가된 PATH. 저기에 DLL들이 위치하고 있다.

설치 후에 다시 실행

그러나 이 모든 것을 다시 설치하고도 문제는 여전.
내가 빌드한 파이썬의 바이너리와 DLL을 모두 지우고, 원래 배포버전으로 돌려놓고 시험해도 마찬가지였다.

그럼 정말 이것도 문제가 아니었단 말인가?

틀림없이 libifcoremd.dll이 설치된 것을 확인했는데도?

그래서 다시 Ollydbg에서 _ufuncs.pyd를 불러 보았다.



헉...이번엔 메시지가 달랐다.

이번엔 libifcoremd.dll이 아니라, libmmd.dll이 문제였고, 그것도 해당 DLL 없다는 것이 아니라 특정 함수의 진입점이 없다는 것.

진전은 있지만 굉장히 불길한 예감.

============================================================================
애초에 이문제는 파이썬의 문제가 아니었다.

생각해 보면 NumPy나 SciPy의 문제도 아니었다.

NumPy나 SciPy를 MS-Windows용으로 빌드를 하는 과정에 어떤 툴을 이용했느냐에 따라 필요로하는 라이브러리나 DLL이 달라질 수 있기 때문이다.

친절한 크리스토프 골케씨가 NumPy와 SciPy를 빌드해서 배포해 주셨지만, 거기에 필요한 Intel의 라이브러리에 대한 충고는 깜빡했다고 밖에 볼 수 없다.
=============================================================================

마지막으로 OllyDbg에서 보여준 메시지에 따라 libmmd.dll을 확인해 보았다.

인텔의 배포 라이브러리 중 C++용과 Fortran용 양쪽 모두에 있는 라이브러리이며, 양쪽 라이브러리 모두 libm_sse2_exp2라는 함수의 이름은 존재하고 있었다.

문제는 정말 함수의 이름만 존재하고 진입점이 없다면....이번엔 인텔의 문제?

2016년 3월 29일 화요일

파이썬의 라이브러리 NumPy + SciPy _____ 7

==========================================================
이 포스팅은 쓸모 없어진 포스팅입니다.
(NumPy + SciPy ____ 4 ~ NumPy + SciPy ____ 8)
해당 문제점은 Scipy 패키지를 빌드했던 툴(아마도 MS Visual Studio 201x)이 Windows XP를 지원하지 않아서 발생한 것으로 추측하고 있습니다.
이후의 포스팅에서 이 시행착오를 정리할 계획입니다. (아마도 NumPy + SciPy ____ 9)
==========================================================

앞서의 포스팅에서 파이썬이 모두 빌드되었다.
(처음엔 뭐가 부족하거나 문제가 있는게 아닌가 싶었는데 확인해 보니 모두 빌드 되어 있었음. 단지 빌드시에 나온 여러개의 워닝 메시지와 스킵한 프로젝트가 뭔지는 아직 미확인.)

빌드의 결과물은 PC/VS9.0 폴더에 있으며, 릴리즈 버전인 python.exe와 python27.dll, 디버그 버전인 python_d.exe와 python27_d.dll이다. (각 써드 파티의 라이브러리는 각 해당 폴더에 있음)

빌드된 python.

배포되는 Python 실행. 빌드버전과 CRC로 보이는 숫자가 있고 다음에 빌드 시각 2015년 12월 5일 20시 32분.

새로 빌드된 Python 실행. 버전 대신 default, 빌드 시각은 2016년 3월 28일 23시 18분.

Python 소스의 트리 구조

Python의 트리 구조

파이썬 소스의 폴더는 바이너리 배포 버전의 폴더와 약간은 다른데, 여기에서 고민이 생긴다.
완벽한 파이썬의 실행 환경이 갖추어져 있지 않으므로 바로 여기에서 디버깅을 하기엔 제약이 따른다는 것이다.

그러면 어떻게 디버깅을 해야 하는가?

1) 빌드된 디버그 버전의 바이너리를 원래의 환경에 복사해 넣고 디버깅을 한다?
소스와 바이너리의 위치가 다를 경우엔 어떻게 해야 하지?
gdb라면 간단하게 소스 위치만 지정하면 될텐데, Visual Studio의 IDE 환경에서도 이게 가능할까?

2) 소스 디렉토리에 필요한 나머지 파일들을 복사해 놓고 디버깅?
파이썬이 비록 인스톨러로 설치가 되긴 하지만, PATH에 경로를 지정하는 것 외에는 별다른 작업이 필요하지 않은 것 같던데? 아닌가?
그리고 Windows/system32 폴더에 python27.dll이 복사되어 있는 것도 보았다.



먼저 2번의 방법을 좀 더 생각해 보다가, 이런 의문이 떠 올랐다.
- 맨 처음의 NumPy와 SciPy를 설치할 때도 특별히 파이썬의 위치를 지정하지 않았지만 알아서 설치가 되었다. 이건 어떻게 가능했을까? (PATH를 보고? 설치 프로그램인 pip의 위치를 기준으로?)
: 이걸 새로 빌드된 환경에서 시험해 보려고 했는데, 아무리 찾아봐도 pip가 보이질 않는다.
 그냥 복사를 해서라도 해 볼까 하다가 걍 포기.

- 파이썬 인터프리터에서 import를 하면 해당 라이브러리를 잘 찾아낸다. 어떻게 가능한걸까?
: 구글에서 "python import dir order"로 검색을 하자 파이썬의 문서에서 "module-search-path" 부분을 찾아서 보여준다.
https://docs.python.org/2/tutorial/modules.html#the-module-search-path

위 링크에서 언급하는 sys.path를 직접 확인해 보았다.

Python의 sys.path

새로 빌드된 Python의 sys.path
환경변수인 PATH에 지정된 경로와는 상관없이, 현재 실행된 위치를 기반으로 내부의 탐색 경로가 바뀌는 것을 알 수 있다.


다시 위의 디버깅에서 1번의 방법에 대해 알아보니, 빌드시에 생성된 pdb에 소스의 위치 정보가 있으므로 바이너와 소스의 위치가 달라도 소스 레벨의 디버깅이 가능하다고 한다......정말일까?

그래서 빌드된 exe, dll, pdb 파일들을 모두 원래의 파이썬이 설치되어 있던 폴더에 복사했다. (원래의 exe와 dll은 다른 폴더에 피신 시켜 둠.)

새로 빌드한 파일들을 파이썬 설치 폴더에 복사

그런데.... 안된다.
Visual Studio에서 읽어 들여 보았으나, 디스어셈블 코드만 보여 줄 뿐, 소스를 찾지 못한다.
심지어 소스 폴더를 지정하는 옵션도 없다.


그래서....Visual Studio에서 프로젝트의 속성을 수정했다.
Python 프로젝트의 속성에서 Debugging의 Command 항목 수정

저기에 직접 디버깅할 실행 파일 이름을 지정해주면 된다.
Debugging 위의 General에서 Output Dir을 바꿔주는 것도 방법이긴 한데, 수정 - 빌드 - 디버깅 작업이 그리 많지 않을거라 생각하기에 최소한만 건드리는 방법을 택한 것이다.

그리고 Visual Studio에서 Start Debugging(F5)을 하면 다음과 같이 나온다.
여기에서 sys.path로 작업중인 디렉토리를 확인할 수 있다.
Start Debugging후에 sys.path로 작업중인 위치 확인.

그리고 그토록 알고자 했던 그 문제점이 재현되는지 확인하기 위해 "from scipy import special, optimize"를 입력하자...

기존의 문제점이 재현되는지 확인....어?
출력되는 메시지가 다르다. 에러는 에러인데....뭔가 이상하다.

아까 디버그와 릴리즈 버전의 바이너리를 모두 복사해 놓은 상태이기에, Visual Studio를 거치지 않고 바로 실행해서 다시 확인해 보았다.


먼저 디버그 버전의 경우..

디버그 버전
역시나 맨 처음과는 다른, Visual Studio를 거쳤을 때와 같은 에러 메시지.

그럼 릴리즈 버전의 경우는...
릴리즈 버전
애초에 보았던 것과 동일한 에러 메시지.

이런 x같은 경우를 보았나.

디버그 버전과 릴리즈 버전의 동작이 서로 다르단 말인가? 왓더뻐~어~억 쒜트 쒜~에~트

메시지를 차근 차근 확인해 본 결과, 릴리즈 버전은 numpy를 먼저 다 import하고 난 후에 scipy의 special을 import하는 중에 에러가 발생했고, 디버그 버전은 numpy를 import하는 과정에서부터 에러가 발생한 것으로 보인다.


침착하고.....
이 문제점이 내가 빌드하는 과정에서 발생한 것인지, 파이썬 자체의 소스 혹은 빌드 구성에 문제가 있는 것인지 알려면 빌드 로그를 모두 꼼꼼하게 확인해 보아야 한다.

그리고 애초에 문제가 되었던 부분에 대한 확인은, 당장은 릴리즈 버전으로 밖에 할 수 없는 상황이고, 이것도 메시지 출력을 이용하거나, 의심되는 부분을 바로 수정해서 확인해 보는 방법 뿐인 듯 하다.

단, 하나의 문제점 때문에 너무나 많은 과정을 거치고 있고, 자꾸 곁가지를 치면서 목표의식마저 흐릿해져 가고 있는 듯 하다.

디버그 버전과 릴리즈 버전의 문제를 확인하기 앞서서, 본래의 문제점을 먼저 해결하길 나 자신에게 바래 본다.

2016년 3월 28일 월요일

파이썬의 라이브러리 NumPy + SciPy _____ 6

==========================================================
이 포스팅은 쓸모 없어진 포스팅입니다.
(NumPy + SciPy ____ 4 ~ NumPy + SciPy ____ 8)
해당 문제점은 Scipy 패키지를 빌드했던 툴(아마도 MS Visual Studio 201x)이 Windows XP를 지원하지 않아서 발생한 것으로 추측하고 있습니다.
이후의 포스팅에서 이 시행착오를 정리할 계획입니다. (아마도 NumPy + SciPy ____ 9)
==========================================================

앞선 포스팅에서 언급한 방법 중, 첫번째인 파이썬 직접 빌드 시도.

파이썬의 창시자가 구글에서 일하고 있으며, 구글의 지원아래 업무시간의 일정 부분을 파이썬 개발에 할애하고 있다고.....누군가한테 들은 적이 있었다.

각설하고...파이썬 소스를 보면서 잠깐 보았던 빌드에 관한 문서를 보고, 빌드 해보고, 실패하고, 인터넷 검색하고, 다시 좌절하고, 귀찮아지고...아마 며칠간은 귀차니즘에 손도 안댔던 거 같다.

그래도 이제 고지가 코 앞이라...는 희망으로 다시 힘을 내 보자.


시작하기 전에 필요한 것들 미리 정리해 보았다.
===========================================

1) 파이썬 소스 : 나는 파이썬 2.7.11을 받아서 빌드하기로 했음. 파이썬 3.x는 Windows Vista 이상에서만 빌드되고 실행되니 이 점은 주의 할 것.

2) 컴파일러 : MS Visual Studio 2008 이상. Express Edition도 된다고 함.

3) SVN client : svn.exe 이름으로 실행되는 command line 버전으로 어디서나 호출 되도록 PATH에 경로 지정 필요.
나는 Tortoise SVN을 사용했는데, 아래 링크된 정성태님의 글에도 나와 있지만 설치시에 반드시 command line client tool을 설치하도록 변경 해 주어야 한다.
그리고 Tortoise SVN은 1.7.15가 Windows XP에 설치되는 마지막 버전이다.(1.9.x & 1.8.x는 설치 안되는 거 확인했음.)
TortoiseSVN 1.9.3

TortoiseSVN 1.9.3 설치 안 됨.ㅠㅠ

TortoiseSVN 1.7.15는 설치 됨. command line client tools는 기본적으로 선택되지 않음.

command line client tools를 설치하도록 바꿈.

Explorere와 연동되는 툴이라서 어지간한 프로그램들을 종료해야 설치 됨.

그러고도 시스템 재시작 필요.


4) Perl interpreter : perl.exe 이름으로 실행되는 command line 버전으로 PATH 경로 지정 필요. 가급적 최신 버전으로 할 것. Strawberry Perl 5.12.2를 이용했으나 에러 발생.
빌드 중 에러 발생. 대놓고 Active Perl 쓰라고 함.
다시 정정. 아마도 Pre-Build event에 뭔가 잘못이 있는 듯 함.
ActivePerl 5.22.1을 설치했으나 다음과 같이 에러 발생.
ActivePerl 설치 후에 build -r로 rebuild한 결과. 마찬가지 에러 발생.
그러나 메시지를 보면, 에러 없이 ssl 라이브러리가 완성되었다.
단지 메시지의 문제였을 뿐?

5) NASM (v2.10 이상) : nasm.exe 이름으로 실행되는 command line 버전으로 PATH 경로 지정 필요.



시작하기 전에 읽어보면 도움이 될 것 들.
=====================================

1) 직접 파이썬을 빌드해 본 경험자의 정리 된 자료
  정성태님의 Python 소스 코드를 Visual C++로 빌드하는 방법 (단, 이건 Python 3.x를 64 bit로 빌드하는 경우)
  저 버전의 파이썬은 조금 예전 버전 경우라 그런지 참 이상한 문제들로 문제를 겪고 있는 부분들이 보인다. 이 버전에서 같은 문제가 발생하지 않을 수 있으니 반드시 증상을 확인한 후에 참조할 것.

2) 파이선 소스에 포함 된 readme.txt 첫번째 : Python-2.7.11/PCBuild/readme.txt

3) 파이선 소스에 포함 된 readme.txt 두번째 : Python-2.7.11/PC/VS9.0/readme.txt



미리 알아두면 좋은 것들.
=======================

1) 파이썬은 시간을 거치면서 많은 기능의 확장이 있었고, 이들 기능 중 일부는 이미 독립적인 라이센스를 가진 소스들을 이용하고 있다. 이런 소스들이 파이썬을 빌드하는데 필요하긴 하지만, 무작정 파이썬 소스에 묶어버리기엔 많은 문제점들이 존재한다. (카피라이트, 라이센스, 버전 관리 등)
따라서 이들 써드 파티의 소스는 별도로 가져와서 빌드를 해야 한다.

2) 위에서 읽어보라고 한 문서를 보면 알겠지만, 문서가 알아보기 쉽거나 간결하지 못하다. 중언 부언에, 내가 원하는 경우를 딱 꼬집어 찾기도 어렵고, 끝까지 읽어 보고 필요한지 아닌지 직접 판단해야 한다.

3) 예전에는 지원했지만, 이제는 지원을 하지 않는다고 없애지 않고 남겨진 폴더들이 있다.
VC6 (Visaul C++ 6.0), VS7.1 (Visual Studio 2003), VS8.0 (Visual Studio 2005)는 더 이상 지원하지 않는다고 하니 쓸데없는 희망을 가지지 말자.



시작
====
명령 프롬프트에서 PC/VS9.0으로 이동해서 build -e를 실행.

이 과정을 통해서 써드파티의 소스를 다운로드 받고 각각을 빌드한다.

문서에서는 pcbuild.sln을 열어서 빌드를 하라고 되어 있지만, 문서를 조금 더 읽어보면 그럴 수 없는 이유들이 나온다.

즉, 초기에 써드파티 소스를 가져오는 과정과 특별히 먼저 빌드되어야 하는 하위 프로젝트들이 존재하기 때문이다.
(하위 프로젝트들 가운데 좀 까다로운 부분이 Open SSL이고, 또 Tcl/Tk 그리고 이를 이용하는 tkinter 부분이라고 되어 있다. 특히 Tcl/Tk 부분은 pcbuild.sln으로는 빌드나 클린이 안되니 반드시 build.bat를 한번은 거쳐야 한다고 한다.)

아마도 처음에 이 부분들이 빌드가 되고 나면, 나머지 파이썬 자체의 소스를 변경하고 빌드하는 과정은 Visual Studio 내에서 가능하리라 생각한다.

build -e, 먼저 받은 소스가 있는 경우에는 skip하고 빌드.

25개 프로젝트 성공, 실패 없음, skip 1개?

이제 각 폴더에 남겨진 BuildLog.htm을 확인해 보고 문제가 없는지 확인해봐야 함.

그리고 Skip된 프로젝트가 무엇인지도...

2016년 3월 21일 월요일

파이썬의 라이브러리 NumPy + SciPy _____ 5

==========================================================
이 포스팅은 쓸모 없어진 포스팅입니다.
(NumPy + SciPy ____ 4 ~ NumPy + SciPy ____ 8)
해당 문제점은 Scipy 패키지를 빌드했던 툴(아마도 MS Visual Studio 201x)이 Windows XP를 지원하지 않아서 발생한 것으로 추측하고 있습니다.
이후의 포스팅에서 이 시행착오를 정리할 계획입니다. (아마도 NumPy + SciPy ____ 9)
==========================================================

정말 정말 궁금했습니다.
왜 나만 안된다고 혼자서 이리도 고생을 하는건지....
정말 미치도록 알고 싶었습니다.

그래서 결국....파이썬의 소스를 보기로 했습니다.

마이크로 소프트가 언급한 DLL의 탐색 경로에 들어가 있음에도 자꾸 DLL을 찾지 못한다고 나오는게 너무 답답해서 누가 잘못하고 있는건지 알아봐야겠습니다.

이젠 귀찮아서 사진도 어지간하면 안올릴 생각이다.

다운로드 받은 소스는 2.7.11
https://www.python.org/downloads/release/python-2711/


소스 분석엔 소스인사이트가 최고.

핵심만 빠르게 찾아가기 위해서 메시지를 바로 찾아 보는게 장땡.

"DLL load failed"라는 문자열로 검색한 결과

dynload_os2.c
dynload_win.c

위의 두개 파일만 검색 된다...그나마 다행.
이름을 보니 볼 거 없이 dynload_win.c가 내가 찾는 파일임이 확실하다.

dynload_win.c

DLL load failed는 저기 보이는 소스에서 조금 더 내려가면 나온다.

저기서 봐야 할 것은 GetFullPathName()과 LoadLibraryEx().

먼저 해당 함수에 대한 MSDN의 설명을 참조.

GetFullPathName()

첫번째 두번째 인자가 입력이고 세번째 네번째가 출력.
그러니까 pathname을 넣고 pathbuf를 받아온 것이다.

그러면 다음엔 pathname이 아닌 pathbuf를 사용해야 할텐데, 다음의 LoadLibraryEx()에서는 pathname을 사용하고 있다.???

LoadLibraryEx()에 대한 설명도 찾아 보자.


LoadLibraryEx()

이 함수는 좀 복잡한데 마지막 인자인 dwFlags에 따라서 DLL 탐색의 순서나 방법이 달라진다고 한다.

LoadLibraryEx()의 dwFlags 설명 중.

이 플래그에 대한 설명도 참 복잡한데, LOAD_WITH_ALTERED_SEARCH_PATH를 사용할 때에는 반드시 파일을 절대 경로로 적어야 한다는 것.
그리고 탐색방법은 아래에 설명....한다고 되어 있는데, 설명이 없다.휴....

다른 페이지에서 설명을 찾았는데,

Dynamic-Link Library Search Order이라는 페이지이고,

여기에서
Alternate Search Order for Desktop Applications
이라는 항목을 찾아보면 설명이 나와 있다.
하지만 해당 항목을 읽어보면 알겠지만 통상적으로 탐색을하는 디렉토리의 순서가 다를 뿐 크게 문제가 되지는 않아보인다.

그렇다면 문제가 될 것으로 예상되는 건, 앞서 LoadLibraryEx()에서 LOAD_WITH_ALTERED_SEARCH_PATH 플래그 사용시 반드시 절대경로를 사용해야 한다는 문구였다. 절대 경로가 아닐 경우에는 결과가 어찌될지 모른다는게 설명...


과연 파이썬 소스에 결정적인 문제가 있어서 이것이 원인이었는지를 확인하려면,

1. 직접 파이썬을 빌드하고 해당 부분을 적절하게 수정한 뒤 문제가 해결되는지 확인한다.

2. 파이썬 3.x의 경우에는 이 부분이 같은지 다른지 확인하고, 또 문제가 발생하는지 여부를 확인해 본다.
  2-1. 파이썬 3.x도 소스가 같고 문제도 동일하게 발생한다면 위의 1번 방법으로 확인해야 한다.
  2-2. 파이썬 3.x도 소스가 같은데 문제가 발생하지 않는다면, 문제의 원인은 다른 곳에 있다는 의미이다. 골치 아픈 케이스.
  2-3. 파이썬 3.x는 소스가 다르고 문제가 발생하지 않는다면 3.x의 소스를 최대한 활용해서 무엇이 문제였는지 최대한 유추해 볼 수 있다. 하지만 결국엔 1번의 과정을 밟아야 한다.
  2-4. 파이썬 3.x는 소스가 다른데 문제가 동일하게 발생한다면 완전히 별개의 문제로서 따로 따로 소스를 분석해야 하지만, 파이썬 소스의 문제가 아니라 내가 사용하는 환경의 문제일 가능성이 높아진다.

3. 최소한의 비용으로 최대한의 결과를 얻기위해 리버싱으로 살짝만 확인해본다.(?)


이상의 계획을 가지고 생각해보니, 먼저 2번의 과정을 거치는게 빠르겠다 싶었다.

그래서 파이썬 3.x의 소스를 받아서 확인해 본 결과....소스가 달랐다.

아예 LoadLibraryEx()를 부르는 함수에 들어오기 전에 먼저 처리를 한게 아닐까 싶게...그래서 소스만으로 비교를 하기엔 무리가 있어서 직접 실행해 보기로 했다.

그.런.데......파이썬 3.x는 Windows Vista이상에서만 돌아간단다.....설치도 안된다...ㅠ.ㅠ

결국 2번의 방법은 몽땅 수포로 돌아가고....

1번의 정공법이냐, 3번의 편법이냐....만 남은 상황이다.