|
최근에 XP machine의 Application이 silently shutdown 되는 현상이 발생하여 Debugger를 걸고 확인해 본 적이 있었다. 마치 Program이 정상적으로 올라오기도 전에 Task manager에서 Process이름만 보였다 사라지는 경우라, program이 실행되지 않은 것인가 의심할 수도 있는 데, Crash에 의해 Shut Down임을 Debugger Break을 통해 확인할 수 있었다. 0:000> kbL 0:000> du 0012e61c 0:000> du 0x0012eb20 Callstack은 마치 Wininet DLL에서 사용하는 Critical Section Object의 Heap Corruption에 의한 Access Violation(AV) 으로 보이지만 사실은 그 전에 알 수 없는 모듈인 tfdsy.tmp file의 load에 의해 유도된 AV가 맞다. 상위의 이름 모를 tmp file(혹은, .dat .bak 등등의 임의의 확장자일 수도 있는 데, 이들은 사실 DLL이나 실행 파일일 수 있다.)은 winmm!LoadAliasedLibrary 에 의해서 load되는 데, 사실 wimm.dll 이 load 되는 것이 해당 머신의 registry key값인 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows 의 AppInit_DLLs 에 winmm.dll이 설정되어 있기 때문에 기본적인 DLL injection 매카니즘에 의해서 load 되는 것이며, 이로 인하여 문제가 있는 모듈(여기서는 tfdsy.tmp file) 역시 load 되어 Application의 Crash를 유발하게 된다. 해당 Issue가 문제 되는 것이 AppInit_DLLs 의 Key에 의한 DLL injection의 경우는 대부분의 process에 DLL을 Injection 시킬 때 사용하는 방법이기 때문에 일부 Application 뿐 만 아닌 백신 프로그램이나 OS에 중요한 프로세스에도 Injection이 되어 Crash가 될 수 있다는 데에 더 큰 이슈가 된다. 확인 결과 AppInit_DLLs 레지스트리 값 뿐만이아니라 LoadAppInit_DLLs에도 1이 설정되어 있으며 이들의 값을 삭제하여도 다시 복원되며, 상위의 알 수 없는 모듈, System32 시스템 폴더에 위치하는 데, 이 역시 삭제하여도 복원되는 악성 코드임으로 밝혀졌다. 이러한 악성코드는 최신의 백신프로그램을 매뉴얼 업데이트하여 치료할 수 있으므로, 더 문제가 되기 전에 확인한다면 문제되지 않을 것이다. (간혹, HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS NT\CurrentVersion\DRIVERS32 "MIDI9 = 랜덤 값" 를 삭제한 후 간혹, tmp file이 삭제되거나 해서 문제를 피해가는 경우가 있다. ) 음식 하나 만드는 데도 정성이 필요하다. 그 정성은 먹는 사람이 알고 느끼게 된다. 예를 들어, 만두 하나를 쪄서 먹더라도 다소 차이가 있다. 요즘, 대형 마트에 가면 흔히 살 수 있는 냉동만두가 있는데 이를 다시마와 멸치 그리고, 양파를 넣고 끊인 물에 적절히 간장으로 간해서 만든 육수에 넣고, 조금 끓인 후에 파를 듬성듬성 썰어 넣고 조금 더 끓여 먹으면 괜찮은 만두국이 된다. 근데, 대형 마트에 있는 만두 말고, 두부나 부추 숙주 돼지고기 등으로 다져진 속에 맛난 만두피로 빚은 손 만두를 쪄 먹거나 국으로 해서 먹으면 그 맛이 냉동만두와 비교하랴. 하물며, 대형 마트산 냉동만두를 국 끓이기는커녕 찌기도 귀찮아 전자렌지에 몇 분 데펴서 수분 빠진 만두를 찐 만두라 먹으며 배고픔이 반찬이 되지 않는 한, 입에 들어 갔을 때, 입안에 만두가 쩍 달라 붙어서 넘기는 데도 힘이 들고, 씹는 데로 비린 돼지고기 냄새를 제거하기 위해 너무 많이 첨가한 후추나 인공감미료의 푸석푸석한 맛이 입맛을 버리게 될지도 모른다. 공자는 고기에 알맞은 양념이 되어 있지 않거나 또는 잘게 썰어있지 않거나, 심지어 고기 빛깔이 좋지 않을 때 젓가락을 들지 않았고, 쌀은 아주 새 하얀 것이 아니면 입에 대지 않았다고 한다. 물론, 이러한 음식 투정은 일반적으로 생각해도 다소 심한 것 같은 데, 그 만큼 음식이 신체에 끼치는 부분을 크게 여겼을 수도 있다. 요즘 누가 공자와 같은 음식 투정을 집에서 할 수 있겠느냐 마는 조금 다르게 본다면 음식을 섭취하여 대단히 만족하고 배가 불렀을 때 그 어떤 세상의 불평 불안이 나를 괴롭힐 수 있겠는가를 느껴보면 달라진다. 그 순간만은 행복 그 자체일 것이다. 공자가 그러한 음식만 입에 댄 것처럼 요즘 세상에 누구에게 그것을 바랄 수 있을 까. 나는 오히려 그러한 누구를 찾기 보다, 스스로 음식을 만드는 기쁨을 느껴 보는 것이 바람직하지 않을 까 한다. 음식을 먹는 즐거움 만큼 내가 좋아하는 음식을 만드는 노동의 기쁨 또한 대단하다고 생각한다. 나는 간혹 샌드위치를 만들어 먹는 데, 넣는 재료에 따라서 달리 맛을 느끼는 재미가 쏠쏠하고 그다지 큰 요리 기술이 필요하지 않음에도 불구하고 약간의 주의가 맛을 좌지우지하는 것이라 흥미롭다. 조금 귀찮지만, 흔한 베이컨을 굽거나 햄을 물에 삶아 준비하고, 달걀을 풀어 후라이팬에 부쳐 식빵크기에 맞게 또한 준비하며, 잘 씻은 토마토는 칼로 갈라 속의 물기를 거의 빼고 한입에 먹기 좋은 크기로 포를 뜨듯이 잘라 만든 후에 살짝 구운 빵이 식기 전에 딸기잼으로 한 면을 발라서 그 위에 계란 부친 것을 올리고 계란이 따끈할 때, 치즈를 올려 녹이고, 그 위에 토마토 썬 것을 올려 캐첩과 머스타드를 섞어 뿌리고 그리고, 햄이나, 베이컨을 그 위에 올려 빵으로 살짝 덮어서 만든 후 빵을 반쯤 썰어 우유와 같이 먹는 다. 근데, 하나의 샌드위치를 만들 때와 여러 개의 샌드위치를 동시에 만들 때 그 맛이 다르다. 간혹, 토마토의 물기가 빵 아래로 흘러내리는 가 하면, 캐첩과 머스타드의 진함이 달라 토마토나 계란 등의 맛을 먹어버리는 경우가 다소 있으며 적절한 시점에 후라이팬에 구운 빵을 사용하지 않으면 샌드위치 내용물에 따라 빵이 눅눅해지거나 또는 빵이 타서 먹기에 입안이 불편할 정도로 거칠어 질수도 있다. 이는 여러 개의 샌드위치를 만드느냐 집중하지 못한 까닭이다. 음식을 만들 때의 정성과 주의는 먹을 때의 행복을 좌지우지 하므로 중요하지만 그보다 중요한 것은 만드는 즐거움이 있어야 먹을 때 역시 즐겁고 행복하다는 것이다. Internet Explorer에 Embedding된 UserControl안에서 Syetem.Net.Sockets.TcpClient를 사용하는 경우, .NET Framework 2.0 SP1이후 Version에서 Hang 현상이 발생할 수 있다. 이는 Internet Explorer환경이 Proxy Server를 이용하여 URL redirect가 되는 경우, redirect되는 URL에 %20 등과 같은 International Characters가 포함되었다면, 이것이 원인이 될 수 있으며 해당 어셈블리가 초기화되는 시점에 다음과 같은 코드를 추가함으로써 이 문제를 피해갈 수 있다. public UserControl1() { Type uriType = typeof(Uri); FieldInfo UriConfigInitField; UriConfigInitField = uriType.GetField("s_ConfigInitialized", BindingFlags.Static | BindingFlags.NonPublic); UriConfigInitField.SetValue(uriType, true); FieldInfo IriParsingField = uriType.GetField("s_IriParsing", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField); IriParsingField.SetValue(uriType, false); FieldInfo IdnScopeField = uriType.GetField("s_IdnScope", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField); IdnScopeField.SetValue(uriType, UriIdnScope.None); //. . . }
이는 다음의 Callstack과 Redirect URL에 International 문자열이 존재하는 지를 가지고 verification할 수 있다. 0:003> !clrstack .." Use the static modifier to declare a static member, which belongs to the type itself rather than to a specific object. The static modifier can be used with classes, fields, methods, properties, operators, events and constructors, but cannot be used with indexers, destructors, or types other than classes. " ... http://msdn.microsoft.com/en-us/library/98f28cdx(VS.80).aspx 하지만, static keyword가 Thread Safe와는 친하지 않기 때문에 Multiple users 나 Threads 환경에서 race condition에 따라 Data가 Corruption되거나 NullReferenceException이 발생할 수도 있다. 0:031> kb ChildEBP RetAddr Args to Child 0d4ff0d4 7923b543 e0434f4d 00000001 00000000 kernel32!RaiseException+0x53 0d4ff12c 7923b4c6 069703b0 00000000 0d4ff388 mscorsvr!RaiseTheException+0xa0 0d4ff154 7923b47a 069703b0 00000000 0d4ff398 mscorsvr!RealCOMPlusThrow+0x48 0d4ff164 79239c8c 069703b0 0000002b 00000000 mscorsvr!RealCOMPlusThrow+0xd 0d4ff398 792b718e 0000002b 00000000 00000000 mscorsvr!CreateMethodExceptionObject+0x67b 0d4ff42c 792b71b2 80004003 00000000 00000000 mscorsvr!RealCOMPlusThrowHRWorker+0xb9 0d4ff448 792b731c 80004003 00000000 00000000 mscorsvr!RealCOMPlusThrowHRWorker+0x15 0d4ff4d4 792a8552 80004003 00000000 0d4ff514 mscorsvr!RealCOMPlusThrowHR+0x168 0d4ff4e8 0268435d 00000000 00000000 80004003 mscorsvr!Interop::ThrowExceptionForHR+0x3a WARNING: Frame IP not in any known module. Following frames may be wrong. 0d4ff660 791f6049 00000001 0d4ff69c 791f609d 0x268435d 0d4ff66c 791f609d 0cafa2d8 0695800c 00000000 mscorsvr!CTPMethodTableCallTargetHelper+0xf 0d4ff69c 791fa7f8 0cafa2d8 0695800c 00000000 mscorsvr!CTPMethodTable::CallTarget+0x4e 0d4ff6c0 791b2682 0cb06e5c 00000000 00000001 mscorsvr!CRemotingServices::CreateProxyOrObject+0x5f 0d4ff730 791b273c 0cb06e5c 0caff013 00000000 mscorsvr!AppDomain::GetOffsetOfSlotsCount+0xa0 0d4ff74c 791b7f92 0d4ff864 791bdd4e 0d4ff7a0 mscorsvr!JIT_NewCrossContext+0x3a 0d4ff754 791bdd4e 0d4ff7a0 00000000 0d4ff778 mscorsvr!CallDescrWorker+0x30 0d4ff864 791d5bd5 00b07f53 026e8a10 024547a0 mscorsvr!MethodDesc::CallDescr+0x1b8 0d4ff88c 79236659 0d4ff8a8 024547a0 0d4ffc8c mscorsvr!MethodDesc::Call+0x8e 0d4ff8b8 792cec0a 069700c8 0d4ff934 02683c9a mscorsvr!CallDefaultConstructor+0x10c 0d4ff8c4 02683c9a 0d4ff8d0 069700c8 0cafec57 mscorsvr!CRemotingServices::CallDefaultCtor+0xd 0:031> !do 069703b0 Name: System.NullReferenceException 0:031> !dumpstack -EE Thread 31 Current frame: ChildEBP RetAddr Caller,Callee 0d4ff51c 0cafd1f5 (MethodDesc 0xcb03410 +0x255 System.EnterpriseServices.Thunk.Proxy.CoCreateObject) 0d4ff548 0cafd107 (MethodDesc 0xcb03410 +0x167 System.EnterpriseServices.Thunk.Proxy.CoCreateObject) 0d4ff600 0cafc0e4 (MethodDesc 0x2643ea0 +0x64 System.Runtime.Remoting.RemotingConfigHandler.IsRemotelyActivatedClientType) 0d4ff608 0cafc6df (MethodDesc 0xcb037d0 +0x1f System.EnterpriseServices.ServicedComponentInfo.SCICachedLookup) 0d4ff610 0cafa8a3 (MethodDesc 0xcb015c8 +0xb3 System.EnterpriseServices.ServicedComponentProxyAttribute.CreateInstance) 0d4ff654 0cafa320 (MethodDesc 0x24fe618 +0x48 System.Runtime.Remoting.Activation.ActivationServices.IsCurrentContextOK) 0d4ff6f0 0caff8f6 (MethodDesc 0xcb07600 +0x6e System.EnterpriseServices.RWHashTableEx.Put) 0d4ff738 0caff013 (MethodDesc 0xcb01710 +0x2b ttt.obj.objMTS..ctor) 0d4ff748 0d50071e (MethodDesc 0xcb07f58 +0x6 ttt.objMain.obj_11..ctor) 0d4ff8d0 0cafec57 (MethodDesc 0x21c9240 +0x7f System.Runtime.Remoting.Proxies.RealProxy.InitializeServerObject) 0d4ff8f4 0cafec95 (MethodDesc 0x21c9240 +0xbd System.Runtime.Remoting.Proxies.RealProxy.InitializeServerObject) 0d4ff920 0cafe77d (MethodDesc 0xcb02e88 +0x85 System.EnterpriseServices.ServicedComponentProxy.SetupContext) 0d4ff934 0cafe683 (MethodDesc 0xcb02d28 +0x1b System.EnterpriseServices.ServicedComponentProxy.ConstructServer) 0d4ff940 0cafe441 (MethodDesc 0xcb02bc8 +0x141 System.EnterpriseServices.ServicedComponentProxy..ctor) 0d4ff96c 0cafe0f2 (MethodDesc 0xcb015f8 +0x8a System.EnterpriseServices.ServicedComponentProxyAttribute.System.Runtime.InteropServices.ICustomFactory.CreateInstance) 0d4ff994 0cafdda3 (MethodDesc 0x24fe628 +0x4b System.Runtime.Remoting.Activation.ActivationServices.CreateObjectForCom) 0d4ffc74 0cafdd24 (MethodDesc 0xcb034a0 +0x6c System.EnterpriseServices.Thunk.Proxy.CallFunction) 0d4ffc98 0cafdd24 (MethodDesc 0xcb034a0 +0x6c System.EnterpriseServices.Thunk.Proxy.CallFunction) 0d4ffcc0 0cafdc87 (MethodDesc 0xcb05a28 +0x67 System.EnterpriseServices.Internal.AppDomainHelper.System.EnterpriseServices.Internal.IAppDomainHelper.DoCallback) 상위 Callstack은 NullReferenceException이 발생한 것을 보여주는 데, ttt.obj.objMTS..ctor Constructor에서의 NulLReferenceException이므로, ttt.obj.objMTS 라는 Class의 초기화에서 NullReferenceException이 발생한 것을 알 수 있다. 하지만, 해당 Dump에서는 몇몇의 Thread가 상위의 NullReferenceException이 발생한 Class의 Constructor와 관련이 있다는 것이다. 아래의 callstack은 상위의 NullReferenceException이 발생한 Constructor의 진행과정을 보여주고 있다. 이게 무엇을 의미하는 가. 0:030> kb ChildEBP RetAddr Args to Child 0d48f0bc 7943b437 024327c0 02430010 02431e5c mscorjit!Compiler::fgSetStmtSeq+0x38 0d48f0d0 7943b466 02431e5c 0d48f328 02430010 mscorjit!Compiler::fgSetBlockOrder+0x17 0d48f0e0 794311b5 00000000 02430010 0d48f13c mscorjit!Compiler::fgSetBlockOrder+0x26 0d48f0f0 79431581 0d48f204 0d48f380 0d48f1f8 mscorjit!Compiler::compCompile+0xa4 0d48f13c 79431622 00130628 0d48f2dc 0d48f328 mscorjit!Compiler::compCompile+0x1e8 0d48f1c4 794316ac 0d48f2dc 0d48f328 0d48f204 mscorjit!jitNativeCode+0x95 0d48f208 791bfd04 79479124 0d48f2dc 0d48f328 mscorjit!CILJit::compileMethod+0xa2 0d48f250 791b91f4 000e38a0 0d48f2dc 0d48f328 mscorsvr!CallCompileMethodWithSEHWrapper+0x52 0d48f3b8 791b95bf 0cb0bab0 0d48f580 0d48f4bc mscorsvr!JITFunction+0x2c7 0d48f4ec 791b4428 0cb0bab0 0d48f580 00000000 mscorsvr!MakeJitWorker+0x2c0 0d48f5d8 791b453f 00000000 0d48f8ec 0d48f614 mscorsvr!MethodDesc::DoPrestub+0x4d3 0d48f5f0 02102f76 0d48f614 00000000 029203b0 mscorsvr!PreStubWorker+0x42 WARNING: Frame IP not in any known module. Following frames may be wrong. 00000000 00000000 00000000 00000000 00000000 0x2102f76 0:030> !dumpstack -EE Thread 30 Current frame: ChildEBP RetAddr Caller,Callee 0d48f61c 0d509747 (MethodDesc 0xcb0baa0 +0x17 System.Xml.XPath.XPathParser.ParseAdditiveExpr) 0d48f634 0d50968f (MethodDesc 0xcb0ba90 +0x17 System.Xml.XPath.XPathParser.ParseRelationalExpr) 0d48f64c 0d509537 (MethodDesc 0xcb0ba80 +0x17 System.Xml.XPath.XPathParser.ParseEqualityExpr) 0d48f664 0d509332 (MethodDesc 0xcb0ba70 +0x12 System.Xml.XPath.XPathParser.ParseAndExpr) 0d48f678 0d5092ba (MethodDesc 0xcb0ba60 +0x12 System.Xml.XPath.XPathParser.ParseOrExpr) 0d48f68c 0d5086d0 (MethodDesc 0xcb0ba30 +0x38 System.Xml.XPath.XPathParser.ParseXPathExpresion) 0d48f698 0d507738 (MethodDesc 0xcb0a3d8 +0x38 System.Xml.XPath.XPathNavigator.Compile) 0d48f6b0 0d5076df (MethodDesc 0xcb0a458 +0x1f System.Xml.XPath.XPathNavigator.Select) 0d48f6c0 0d506e6c (MethodDesc 0xc8609e8 +0x24 System.Xml.XmlNode.SelectSingleNode) 0d48f6e4 0d500391 (MethodDesc 0xcb06a98 +0x79 aaa.ClassMain.Config.xmlLoad) 0d48f728 0caff1d1 (MethodDesc 0xcb06a38 +0x79 aaa.ClassMain.Config..ctor) 0d48f730 0caff0d0 (MethodDesc 0xcb06a58 +0x28 aaa.ClassMain.Config.GetConfig) 0d48f738 0cafeff9 (MethodDesc 0xcb01710 +0x11 ttt.obj.objMTS..ctor) 0d48f748 0caff08e (MethodDesc 0xcb01820 +0x6 ttt.objMain.obj_Comp..ctor) 0d48f8d0 0cafec57 (MethodDesc 0x21c9240 +0x7f System.Runtime.Remoting.Proxies.RealProxy.InitializeServerObject) 0d48f8f4 0cafec95 (MethodDesc 0x21c9240 +0xbd System.Runtime.Remoting.Proxies.RealProxy.InitializeServerObject) 0d48f920 0cafe77d (MethodDesc 0xcb02e88 +0x85 System.EnterpriseServices.ServicedComponentProxy.SetupContext) 0d48f934 0cafe683 (MethodDesc 0xcb02d28 +0x1b System.EnterpriseServices.ServicedComponentProxy.ConstructServer) 0d48f940 0cafe441 (MethodDesc 0xcb02bc8 +0x141 System.EnterpriseServices.ServicedComponentProxy..ctor) 0d48f96c 0cafe0f2 (MethodDesc 0xcb015f8 +0x8a System.EnterpriseServices.ServicedComponentProxyAttribute.System.Runtime.InteropServices.ICustomFactory.CreateInstance) 0d48f994 0cafdda3 (MethodDesc 0x24fe628 +0x4b System.Runtime.Remoting.Activation.ActivationServices.CreateObjectForCom) 0d48fc74 0cafdd24 (MethodDesc 0xcb034a0 +0x6c System.EnterpriseServices.Thunk.Proxy.CallFunction) 0d48fc98 0cafdd24 (MethodDesc 0xcb034a0 +0x6c System.EnterpriseServices.Thunk.Proxy.CallFunction) 0d48fcc0 0cafdc87 (MethodDesc 0xcb05a28 +0x67 System.EnterpriseServices.Internal.AppDomainHelper.System.EnterpriseServices.Internal.IAppDomainHelper.DoCallback) Callstack만 봐서는 문제가 없어 보일 수 있다. 단지, ttt.obj.objMTS..ctor 가 호출되는 2개의 Threads를 본 것이기 때문이다. 하지만, 여기서 ttt.obj.objMTS class의 Constructor안에서 호출되는 aaa.ClassMain.Config.GetConfig function을 들여다 보면, 다음과 같다. .method public hidebysig static class aaa.ClassMain.Config.GetConfig GetConfig() cil managed { // Code size 23 (0x17) .maxstack 1 IL_0000: ldsfld class aaa.ClassMain.Config aaa.ClassMain.Config::self IL_0005: brtrue.s IL_0011 IL_0007: newobj instance void aaa.ClassMain.Config::.ctor() IL_000c: stsfld class aaa.ClassMain.Config aaa.ClassMain.Config::self IL_0011: ldsfld class aaa.ClassMain.Config aaa.ClassMain.Config::self IL_0016: ret } // end of method Config::GetConfig .field private static class aaa.ClassMain.Config self 즉, aaa.ClassMain.Config.GetConfig 는 static function이며, 그 보다, 그 안에서 Initialize 되는 aaa.ClassMain.Config Class는 self 라는 static variable 로 assign 이 된다. 물론, 예상대로 aaa.ClassMain.Config 는 Config File의 XML data를 load 하여 parsing 및 저장하여 가지고 있는 개체이다. 하지만, 이러한 data 들은 결코 Thread-safe 하지 않는 상태로 Multiple Threads에 의해서 접근이 가능하다는 것이며, 이러한 data의 초기화 시점에 race condition이 발생한다는 데 있다. 상위의 Callstack (System.EnterpriseServices.Thunk.Proxy.CoCreateObject )을 보면, 예상할 수 있겠지만, 이는 COM+ 혹은 Enterprise Services Application Call이며, Object Pooling과 같은 구조의 Component 초기화는 그러한 위험성을 내포하고 있다. 이와 같은 상황에 대해서 문서 http://support.microsoft.com/kb/893666/en-us " Troubleshooting ASP.NET applications with the use of static keywords" 에서는 여러 가지 우려한 시나리오를 언급하고 있다. 이것도 그 중 하나일 것이다. 상위의 문제를 해결하기 위해서는 우선적으로 Thread-Safe 하게 접근하는 것이 우선적일 것이다. Static Keyword 를 사용하지 않는 것도 필요하다면 고려할 수 있지만, Data의 Locking이나 Synchronization 을 고려한 코드의 일부 수정으로써 문제를 풀어나가는 것도 고려해 볼 수 있지 않나 본다. 모처럼 회사 동료의 결혼식에서 주례사의 말씀을 찬찬히 들어볼 기회가 있었는데, 시작이 돌아가신 전대통령의 일기에 언급된 인생은 아름다고, 역사는 … 이었다. 이어서 이어지는 돌아가신 박경리선생님의 말씀도.. 역시 같은 맥락인 인생은 너무나도 아름답다는 것이다. 결혼을 통해서 새롭게 시작하는 이들에게는 필요한 말이 아닐까 한다. 물론, 잊지 않고 고달픔이 있을 것이라는 것, 이것을 직시하고 슬기롭게 이겨내는 것도 필요함을 잊지 않으셨다. 사실 기억해보면, 나 같이 아무 생각 없이 결혼식에 참가하여 다소 지루함을 못 견뎌 주례사의 말씀을 식사 나오기 전까지의 killing time 용으로 경청하는 사람 및 몇몇을 제외하고는 당사자인 분들을 포함해 정신 없이 바쁜 이들에게는 이러한 좋은 어구가 들렸을 까. 여태 수 십 차례 결혼식을 참가했지만, 이렇게 맘에 와 닫는 주례사는 처음이었다. 항상 형식적인 결혼식의 참가와 형식적인 축하 그리고, 한끼를 때우는 욕심 등이 지금까지 나의 태도에 있어서 부끄럽게 만들었다. 죽음 자체는 아무런 의미가 없고.. 인생이 너무나 아름답다. (아.. Old and Wise,) 이 말을 이해하기엔 난 아직 어린것 같다. 사실 우리가 살아가는 동안 행복하다고 느낄 때에는 사소한 것들조차 기쁨으로 다가오며, 이때에는 누가 뭐라 해도 인생은 아름답다고 느끼지 않을 까. 하지만, 조금이라도 불행하다면, 과연 인생은 아름답다라고 느낄 수 있을 까. 최근에 읽은 러셀의 “행복의 정복”을 보면, 우리가 왜 불행한가에 대한 언급이 있다. 병이나 배고픔과 같은 기본적인 육체적인 고통을 제외하고라도 정신적으로 만족스럽지 못해서 발생하는 불행의 원인인 즉, 경쟁, 권태, 자극, 피로, 질투, 피해망상, 죄의식 및 대중에 대한 두려움에 대해서는 하나씩 직시하고 언급하였다. 특히 알랭드 보통의 “불안”에서도 언급된 peer간의 경쟁과 질투는 결코 알면서도 올바로 의식하지 못했던 부분이다. 사실 범접할 수 없던 태생적으로 다른 이와의 비교에서는 질투보다는 체념이 따르기 때문에 포기되는 부분으로 스스로를 괴롭히진 않는 다. 하지만, 지금 같은 만민 평등 시대에서 똑같은 조건에서 태어나고 자랐다고 여기는 주변의 누구는 소위 부동산에, 주식에 일가견이 있어서 지금 시대의 성공의 척도가 되는 재화의 축적을 보란 듯이 했다는 소식만 들어도 그에 따른 질투와 열등감 그리고, 경쟁의식에 피곤하고 불행해진다. 그와 반대로 부에 대해서 끊임없이 추구하여 이들의 부러움을 사는 이들조차 지속적인 부의 축적 및 이에 대한 유지를 위한 쉬지 않는 경쟁 및 피로, 그리고, 경쟁 이후에 오는 권태, 이를 모면하려는 자극, 그 이후의 공허감이 정신을 또한 피폐하게 만든다. 이러한 정신의 상태에서도 인생은 정말 아름다운 것이야 라고 느낄 수 있을 까. 상위에 언급한 두 작가는 몇 가지의 불행을 막기 위한 태도에 대해서 언급하고 있는데, 그 중에서 일부 기억에 남는 것으로 지금 그렇게 목매달고 불안해 하고 불행해하는 태도가 원대한 이 우주에서 나라는 존재가 차지하는 것만큼이나 얼마나 보잘것없는 지에 대한 생각의 전환이나, 현실에서의 재화보다 저 세상에서의 재화를 쌓는 부분에 초점을 맞추는 기독교적인 사고가 도움이 될 수 있음을 (내가 이해한 것이 맞다는 가정에) 언급하고 있다. 하지만, 이것이 그리 쉬운 길은 아니다. 물론, 나라는 존재가 이 방대한 우주에 비하면 하잘 것이 없으며, 내가 고민하거나 끊임없이 내 신경을 거슬리며 밤잠을 자지 못하게 하는 그것이 시간이 지나면 왜 그리 고민했었나 할 정도로 미미한 것일 지라도 그 순간에는 대의적인 사고가 되지 않는 것이 인간이다. 또한 기독교적인 인간 역시도 성서를 기반으로 한 이상적인 규율 안에서도 내가 물질적으로 소유하고 있는 부분에 대해서 끊임없이 갈등하는 것이 인간이다. (개인적인 생각으로는) 이것이 인생을 아름답게 만드는 방법이 될 수는 있으나 도 닦는 수준을 원하는 이러한 방법은 끊임없는 자기 최면이나 수양 그리고 노력이 필요하다. 그에 비하면, mental tiring과 같은 불행은 이를 잠시라도 잊을 수 있거나 이를 다소 누그러뜨릴 수 있는, 무언가 다 집어 치우고 몰두할 수 있는 취미의 발굴이 더 쉬운 접근법일 수 있다. 더불어, 러셀도 언급했지만, 직업에 대해서, 몰두할 수 있는 취미도 중요하지만, 그와 마찮가지로 몰두할 수 있는 적절한 직업의 선택 역시 중요하다. 요즘, 청년실업의 증가와 함께 이도 역시 쉽지 않은 가운데, 한비아씨가 어느 TV프로그램에서 언급한 이야기가 가슴을 훔친다. 가슴 떨리는, 가슴 벅차게 만드는 일을 찾는 것, 이것이 가장 좋은 방법이 아닐 까 한다. 아마, 인생이 아름답다라고 느끼고 싶다면 …. “무엇이 내 가슴을 뛰게 하는 가”에 대한 답변을 낼 수 있으며, 그를 행동으로 옮길 수 있는 용기 ….
|
카테고리
이글루링크
최근 등록된 덧글
글 잘 읽었습니다 .
전 ..
by 위시 at 11/26 어렷다 by klhk at 11/09 dhjjgbem by kl at 11/09 17번부터 어떻게 접는지.. by tykim0131 at 10/28 ATL이나 MFC를 이용하.. by 김명신 at 09/24 복원되었군요.. 제 RSS.. by 강세윤 at 09/24 허걱, 하고 있는 것으로.. by 강세윤 at 09/15 RSS 주소 서비스는 안 .. by 정성태 at 09/15 다시 보고 싶군요. by 강세윤 at 09/14 마악하임 ㄱ-;;; ㅋㅋㅋ.. by ㅋㅋㅋ at 09/13 이글루 파인더
| |||