뭉근 : 느긋하게 타는 불

Connected to Windows 8 9841 x86 compatible target at (Fri Nov 14 08:06:42.382 2014 (UTC + 9:00)), ptr64 FALSE
Kernel Debugger connection established.

************* Symbol Path validation summary **************
Response                         Time (ms)     Location
Deferred                                       srv*D:\WebSymbols*http://msdl.microsoft.com/download/symbols
Symbol search path is: srv*D:\WebSymbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
Windows 8 Kernel Version 9841 MP (1 procs) Free x86 compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 9841.0.x86fre.fbl_release.140912-1613
Machine Name:
Kernel base = 0x81276000 PsLoadedModuleList = 0x8148d6d8
Debug session time: Fri Nov 14 08:06:36.550 2014 (UTC + 9:00)
System Uptime: 0 days 0:05:40.451
Break instruction exception - code 80000003 (first chance)

// 기존 8.1의 경우 9600임

 

kd> !pcr
KPCR for Processor 0 at 814a0000:
    Major 1 Minor 1
 NtTib.ExceptionList: 827e6f6c
     NtTib.StackBase: 00000000
    NtTib.StackLimit: 00001f80
  NtTib.SubSystemTib: 807d5000
       NtTib.Version: 0002e7cc
   NtTib.UserPointer: 00000001
       NtTib.SelfTib: 00000000

             SelfPcr: 814a0000
                Prcb: 814a0120
                Irql: 0000001f
                 IRR: 00000000
                 IDR: 00000000
       InterruptMode: 00000000
                 IDT: 807e1400
                 GDT: 807e1000
                 TSS: 807d5000

       CurrentThread: 814be200
          NextThread: 00000000
          IdleThread: 814be200

           DpcQueue: Unable to read nt!_KDPC_DATA.DpcListHead.Flink @ 814a2300

kd> dd nt!KiInitialPCR
814a0000  827e6f6c 00000000 00001f80 807d5000
814a0010  0002e7cc 00000001 00000000 814a0000
814a0020  814a0120 0000001f 00000000 00000000
814a0030  00000000 81473d40 807e1400 807e1000
814a0040  807d5000 00010001 00000001 00000d40
814a0050  00000000 00000000 00000000 00000000
814a0060  00000000 00000000 00000000 00000000
814a0070  00000000 00000000 00000000 00000000

kd> dt _KPCR 814a0000
nt!_KPCR
   +0x000 NtTib            : _NT_TIB
   +0x000 Used_ExceptionList : 0x827e6f6c _EXCEPTION_REGISTRATION_RECORD
   +0x004 Used_StackBase   : (null)
   +0x008 MxCsr            : 0x1f80
   +0x00c TssCopy          : 0x807d5000 Void
   +0x010 ContextSwitches  : 0x2e7cc
   +0x014 SetMemberCopy    : 1
   +0x018 Used_Self        : (null)
   +0x01c SelfPcr          : 0x814a0000 _KPCR
   +0x020 Prcb             : 0x814a0120 _KPRCB
   +0x024 Irql             : 0x1f ''
   +0x028 IRR              : 0
   +0x02c IrrActive        : 0
   +0x030 IDR              : 0
   +0x034 KdVersionBlock   : 0x81473d40 Void
   +0x038 IDT              : 0x807e1400 _KIDTENTRY
   +0x03c GDT              : 0x807e1000 _KGDTENTRY
   +0x040 TSS              : 0x807d5000 _KTSS
   +0x044 MajorVersion     : 1
   +0x046 MinorVersion     : 1
   +0x048 SetMember        : 1
   +0x04c StallScaleFactor : 0xd40
   +0x050 SpareUnused      : 0 ''
   +0x051 Number           : 0 ''
   +0x052 Spare0           : 0 ''
   +0x053 SecondLevelCacheAssociativity : 0 ''
   +0x054 VdmAlert         : 0
   +0x058 KernelReserved   : [14] 0
   +0x090 SecondLevelCacheSize : 0
   +0x094 HalReserved      : [16] 0x1000000
   +0x0d4 InterruptMode    : 0
   +0x0d8 Spare1           : 0 ''
   +0x0dc KernelReserved2  : [17] 0
   +0x120 PrcbData         : _KPRCB

 

// KPCR 크기는 역시나 계속 동일함


kd> dt _KPRCB 814a0000+120
nt!_KPRCB
   +0x000 MinorVersion     : 1
   +0x002 MajorVersion     : 1
   +0x004 CurrentThread    : 0x814be200 _KTHREAD
   +0x008 NextThread       : (null)
   +0x00c IdleThread       : 0x814be200 _KTHREAD
   +0x010 LegacyNumber     : 0 ''
   +0x011 NestingLevel     : 0x1 ''
   +0x012 BuildType        : 0
   +0x014 CpuType          : 6 ''
   +0x015 CpuID            : 1 ''
   +0x016 CpuStep          : 0x3a09
   +0x016 CpuStepping      : 0x9 ''
   +0x017 CpuModel         : 0x3a ':'
   +0x018 ProcessorState   : _KPROCESSOR_STATE
   +0x338 ParentNode       : 0x8147d080 _KNODE
   +0x33c PriorityState    : 0x814a4948  ""
   +0x340 KernelReserved   : [14] 0
   +0x378 HalReserved      : [16] 0xa6a600
   +0x3b8 CFlushSize       : 0x40
   +0x3bc CoresPerPhysicalProcessor : 0x1 ''
   +0x3bd LogicalProcessorsPerCore : 0x1 ''
   +0x3be CpuVendor        : 0x1 ''
   +0x3bf PrcbPad0         : [1]  ""
   +0x3c0 MHz              : 0xd40
   +0x3c4 GroupIndex       : 0 ''
   +0x3c5 Group            : 0 ''
   +0x3c6 PrcbPad05        : [2]  ""
   +0x3c8 GroupSetMember   : 1
   +0x3cc Number           : 0
   +0x3d0 ClockOwner       : 0x1 ''
   +0x3d1 PendingTickFlags : 0x1 ''
   +0x3d1 PendingTick      : 0y1
   +0x3d1 PendingBackupTick : 0y0
   +0x3d2 PrcbPad10        : [70]  ""
   +0x418 LockQueue        : [17] _KSPIN_LOCK_QUEUE
   +0x4a0 InterruptCount   : 0xa968
   +0x4a4 KernelTime       : 0x5314
   +0x4a8 UserTime         : 0x208
   +0x4ac DpcTime          : 0x37
   +0x4b0 DpcTimeCount     : 0
   +0x4b4 InterruptTime    : 0x12
   +0x4b8 AdjustDpcThreshold : 2
   +0x4bc PageColor        : 0x320d
   +0x4c0 DebuggerSavedIRQL : 0x1c ''
   +0x4c1 NodeColor        : 0 ''
   +0x4c2 PrcbPad20        : [6]  ""
   +0x4c8 NodeShiftedColor : 0
   +0x4cc SecondaryColorMask : 0x3f
   +0x4d0 DpcTimeLimit     : 0
   +0x4d4 DeviceInterruptCount : 0x524c
   +0x4d8 PrcbPad21        : [2] 0
   +0x4e0 CcFastReadNoWait : 0
   +0x4e4 CcFastReadWait   : 0x1464
   +0x4e8 CcFastReadNotPossible : 0
   +0x4ec CcCopyReadNoWait : 0
   +0x4f0 CcCopyReadWait   : 0x1913
   +0x4f4 CcCopyReadNoWaitMiss : 0
   +0x4f8 MmSpinLockOrdering : 0n0
   +0x4fc IoReadOperationCount : 0n7105
   +0x500 IoWriteOperationCount : 0n5147
   +0x504 IoOtherOperationCount : 0n104510
   +0x508 IoReadTransferCount : _LARGE_INTEGER 0xbd1ff8a
   +0x510 IoWriteTransferCount : _LARGE_INTEGER 0x19bb1be
   +0x518 IoOtherTransferCount : _LARGE_INTEGER 0x55e32e
   +0x520 CcFastMdlReadNoWait : 0
   +0x524 CcFastMdlReadWait : 0
   +0x528 CcFastMdlReadNotPossible : 0
   +0x52c CcMapDataNoWait  : 0
   +0x530 CcMapDataWait    : 0xed39
   +0x534 CcPinMappedDataCount : 0xfa2
   +0x538 CcPinReadNoWait  : 0
   +0x53c CcPinReadWait    : 0x647
   +0x540 CcMdlReadNoWait  : 0
   +0x544 CcMdlReadWait    : 6
   +0x548 CcLazyWriteHotSpots : 0x2f
   +0x54c CcLazyWriteIos   : 0x211
   +0x550 CcLazyWritePages : 0x61c
   +0x554 CcDataFlushes    : 0x4b3
   +0x558 CcDataPages      : 0x16bd
   +0x55c CcLostDelayedWrites : 0
   +0x560 CcFastReadResourceMiss : 0
   +0x564 CcCopyReadWaitMiss : 0x944d
   +0x568 CcFastMdlReadResourceMiss : 0
   +0x56c CcMapDataNoWaitMiss : 0
   +0x570 CcMapDataWaitMiss : 0xe61
   +0x574 CcPinReadNoWaitMiss : 0
   +0x578 CcPinReadWaitMiss : 0x3a
   +0x57c CcMdlReadNoWaitMiss : 0
   +0x580 CcMdlReadWaitMiss : 0
   +0x584 CcReadAheadIos   : 0x851
   +0x588 KeAlignmentFixupCount : 0
   +0x58c KeExceptionDispatchCount : 0x2dc
   +0x590 KeSystemCalls    : 0x1e6ee1
   +0x594 AvailableTime    : 0x84
   +0x598 PrcbPad22        : [2] 0
   +0x5a0 PPLookasideList  : [16] _PP_LOOKASIDE_LIST
   +0x620 PPNxPagedLookasideList : [32] _GENERAL_LOOKASIDE_POOL
   +0xf20 PPNPagedLookasideList : [32] _GENERAL_LOOKASIDE_POOL
   +0x1820 PPPagedLookasideList : [32] _GENERAL_LOOKASIDE_POOL
   +0x2120 PacketBarrier    : 0
   +0x2124 ReverseStall     : 0n2
   +0x2128 IpiFrame         : (null)
   +0x212c PrcbPad3         : [52]  ""
   +0x2160 CurrentPacket    : [3] (null)
   +0x216c TargetSet        : 0
   +0x2170 WorkerRoutine    : (null)
   +0x2174 IpiFrozen        : 0
   +0x2178 PrcbPad4         : [40]  ""
   +0x21a0 RequestSummary   : 0
   +0x21a4 SignalDone       : (null)
   +0x21a8 PrcbPad50        : [40]  ""
   +0x21d0 InterruptLastCount : 0xa968
   +0x21d4 InterruptRate    : 4
   +0x21d8 DeviceInterrupts : 0x30
   +0x21dc IsrDpcStats      : 0x00000001 Void
   +0x21e0 DpcData          : [2] _KDPC_DATA
   +0x2210 DpcStack         : 0x827ec000 Void
   +0x2214 MaximumDpcQueueDepth : 0n4
   +0x2218 DpcRequestRate   : 4
   +0x221c MinimumDpcRate   : 3
   +0x2220 DpcLastCount     : 0x9dfd
   +0x2224 PrcbLock         : 0
   +0x2228 DpcGate          : _KGATE
   +0x2238 IdleState        : 0 ''
   +0x2239 QuantumEnd       : 0 ''
   +0x223a DpcRoutineActive : 0 ''
   +0x223b IdleSchedule     : 0 ''
   +0x223c DpcRequestSummary : 0n8
   +0x223c DpcRequestSlot   : [2] 0n8
   +0x223c NormalDpcState   : 0n8
   +0x223e ThreadDpcState   : 0n0
   +0x223c DpcNormalProcessingActive : 0y0
   +0x223c DpcNormalProcessingRequested : 0y0
   +0x223c DpcNormalThreadSignal : 0y0
   +0x223c DpcNormalTimerExpiration : 0y1
   +0x223c DpcNormalDpcPresent : 0y0
   +0x223c DpcNormalLocalInterrupt : 0y0
   +0x223c DpcNormalSpare   : 0y0000000000 (0)
   +0x223c DpcThreadActive  : 0y0
   +0x223c DpcThreadRequested : 0y0
   +0x223c DpcThreadSpare   : 0y00000000000000 (0)
   +0x2240 LastTimerHand    : 0x32ba
   +0x2244 LastTick         : 0x551c
   +0x2248 PeriodicCount    : 0
   +0x224c PeriodicBias     : 0
   +0x2250 ClockInterrupts  : 0x57bc
   +0x2254 ReadyScanTick    : 0x5565
   +0x2258 GroupSchedulingOverQuota : 0 ''
   +0x2259 ThreadDpcEnable  : 0x1 ''
   +0x225a PrcbPad41        : [2]  ""
   +0x2260 TimerTable       : _KTIMER_TABLE
   +0x3aa0 CallDpc          : _KDPC
   +0x3ac0 ClockKeepAlive   : 0n1
   +0x3ac4 PrcbPad6         : [4]  ""
   +0x3ac8 DpcWatchdogPeriod : 0n0
   +0x3acc DpcWatchdogCount : 0n1
   +0x3ad0 KeSpinLockOrdering : 0n0
   +0x3ad4 PrcbPad70        : [1] 0
   +0x3ad8 QueueIndex       : 1
   +0x3adc DeferredReadyListHead : _SINGLE_LIST_ENTRY
   +0x3ae0 ReadySummary     : 0
   +0x3ae4 AffinitizedSelectionMask : 0n262135
   +0x3ae8 WaitLock         : 0
   +0x3aec WaitListHead     : _LIST_ENTRY [ 0x9c6980dc - 0x97ac749c ]
   +0x3af4 ScbOffset        : 0x40
   +0x3af8 StartCycles      : 0x000002b9`cd5fac50
   +0x3b00 TaggedCyclesStart : 0
   +0x3b08 TaggedCycles     : [2] 0
   +0x3b18 GenerationTarget : 0x5538
   +0x3b20 CycleTime        : 0x00000009`eabff3e4
   +0x3b28 AffinitizedCycles : 0
   +0x3b30 HighCycleTime    : 9
   +0x3b34 PrcbPad71        : [11] 0
   +0x3b60 DispatcherReadyListHead : [32] _LIST_ENTRY [ 0x814a3c80 - 0x814a3c80 ]
   +0x3c60 ChainedInterruptList : (null)
   +0x3c64 LookasideIrpFloat : 0n2147483647
   +0x3c68 ScbQueue         : _RTL_RB_TREE
   +0x3c70 ScbList          : _LIST_ENTRY [ 0x89ac7100 - 0x89ac7100 ]
   +0x3c78 MmPageFaultCount : 0n612791
   +0x3c7c MmCopyOnWriteCount : 0n11038
   +0x3c80 MmTransitionCount : 0n184606
   +0x3c84 MmCacheTransitionCount : 0n0
   +0x3c88 MmDemandZeroCount : 0n368214
   +0x3c8c MmPageReadCount  : 0n102675
   +0x3c90 MmPageReadIoCount : 0n13991
   +0x3c94 MmCacheReadCount : 0n0
   +0x3c98 MmCacheIoCount   : 0n0
   +0x3c9c MmDirtyPagesWriteCount : 0n61586
   +0x3ca0 MmDirtyWriteIoCount : 0n421
   +0x3ca4 MmMappedPagesWriteCount : 0n0
   +0x3ca8 MmMappedWriteIoCount : 0n0
   +0x3cac CachedCommit     : 0x100
   +0x3cb0 CachedResidentAvailable : 0x79
   +0x3cb4 HyperPte         : 0x8001000f Void
   +0x3cb8 PrcbPad8         : [4]  ""
   +0x3cbc VendorString     : [13]  "GenuineIntel"
   +0x3cc9 InitialApicId    : 0 ''
   +0x3cca LogicalProcessorsPerPhysicalProcessor : 0x1 ''
   +0x3ccb PrcbPad9         : [1]  ""
   +0x3cd0 FeatureBits      : 0xa3cf3fff
   +0x3cd8 UpdateSignature  : _LARGE_INTEGER 0x00000017`00000000
   +0x3ce0 IsrTime          : 0
   +0x3ce8 PrcbPad90        : [2] 0
   +0x3cf0 PowerState       : _PROCESSOR_POWER_STATE
   +0x3e70 PrcbPad91        : [18] 0
   +0x3eb8 DpcWatchdogDpc   : _KDPC
   +0x3ed8 DpcWatchdogTimer : _KTIMER
   +0x3f00 HypercallPageList : _SLIST_HEADER
   +0x3f08 HypercallPageVirtual : 0xffd06000 Void
   +0x3f0c VirtualApicAssist : (null)
   +0x3f10 StatisticsPage   : (null)
   +0x3f14 Cache            : [5] _CACHE_DESCRIPTOR
   +0x3f50 CacheCount       : 4
   +0x3f54 PackageProcessorSet : _KAFFINITY_EX
   +0x3f60 SharedReadyQueueMask : 0
   +0x3f64 SharedReadyQueue : 0x814a4840 _KSHARED_READY_QUEUE
   +0x3f68 CoreProcessorSet : 1
   +0x3f6c ScanSiblingMask  : 0
   +0x3f70 LLCMask          : 1
   +0x3f74 CacheProcessorMask : [5] 1
   +0x3f88 ScanSiblingIndex : 0
   +0x3f8c WheaInfo         : 0x8035a170 Void
   +0x3f90 EtwSupport       : 0x803258c0 Void
   +0x3f98 InterruptObjectPool : _SLIST_HEADER
   +0x3fa0 PrcbPad92        : [3] 0
   +0x3fac PteBitCache      : 0x3fffff
   +0x3fb0 PteBitOffset     : 0x19b00
   +0x3fb4 PrcbPad93        : 0
   +0x3fb8 ProcessorProfileControlArea : (null)
   +0x3fbc ProfileEventIndexAddress : 0x814a40dc Void
   +0x3fc0 TimerExpirationDpc : _KDPC
   +0x3fe0 SynchCounters    : _SYNCH_COUNTERS
   +0x4098 FsCounters       : _FILESYSTEM_DISK_COUNTERS
   +0x40a8 Context          : 0x81a44340 _CONTEXT
   +0x40ac ContextFlagsInit : 0x1006f
   +0x40b0 ExtendedState    : 0x81a44000 _XSAVE_AREA
   +0x40b4 EntropyTimingState : _KENTROPY_TIMING_STATE
   +0x41dc IsrStack         : 0x827f0000 Void
   +0x41e0 VectorToInterruptObject : [208] (null)
   +0x4520 AbSelfIoBoostsList : _SINGLE_LIST_ENTRY
   +0x4524 AbPropagateBoostsList : _SINGLE_LIST_ENTRY
   +0x4528 AbDpc            : _KDPC
   +0x4548 IoIrpStackProfilerCurrent : _IOP_IRP_STACK_PROFILER
   +0x459c IoIrpStackProfilerPrevious : _IOP_IRP_STACK_PROFILER
   +0x45f0 TimerExpirationTrace : [16] _KTIMER_EXPIRATION_TRACE
   +0x46f0 TimerExpirationTraceCount : 5
   +0x46f4 ExSaPageArray    : 0x80250718 Void
   +0x46f8 PrcbPad100       : [10] 0
   +0x4720 LocalSharedReadyQueue : _KSHARED_READY_QUEUE

// 멤버 추가 됨.. 천천히 수정

 

 

이번 포스트의 시작과 함께…

이런 경우는 도대체 언제 발생하는가 생각이 든다…

왜 8바이트를 컴파일러에서는 이런 식으로 처리하게 되었는가? 부터 시작해서

VC 컴파일러는 믿을만 한가? 라는 생각도 들게하는 문제이다.

일단 문제는 잘 사용되던 코드에서 갑자기 에러가 나면서 시작됐다.

에러가 난 코드는 다음 그림과 같다.

VC를 조금이라도 다뤄본 사람은 0xCC로 채워진 메모리는 초기화되지 않은 영역을 의미한다는 것을 알것이다. 근데 나는 분명히 0으로 초기화를 했으며… 8바이트 중 4바이트만 일부러 0xcc를 채우지도 않았다.

아래는 위 상태의 this 메모리 영역이다. (m_nDTB를 채우기전)

 

첫 4바이트는 vftable을 나타낸다. 문제는 그 뒤 메모리를 어떻게 사용하느냐인데… 아래를 디스어셈블 내용을 보면 알 수 있다.

 

디스어셈블을 보면 전달 인자인 _nDTB를 스택에 하위 4바이트를 넣고 edx에 상위 4바이트를 전달하여 처리한다. 처리할 때 메모리 영역을 보면 this + 0x08 부터 4바이트, 4바이트 단위로 8바이트 변수인 m_nDTB 변수에 채워넣는 것을 볼 수 있다. edx는 당연히 0이다.

이쯤 되면 코드에는 아무 문제가 없어보인다. 그런데 다시 맨 위 m_nDTB 값을 보면 이상하다는 것을 느낄 수 있을 것이다. 위 코드로 볼 때 m_nDTB가 메모리 상에서는 0으로 채워져있다는 것을… 하지만 실제 m_nDTB 값은 아래와 같이 값을 채운 후에도 이상하다는 것을…

 

위 그림은 Address 부분에  &m_nDTB를 입력했을 때 나온 결과이다. 즉, 실제 8 바이트 m_nDTB 변수 사용은 this + 0x04 인 영역부터 8바이트인 것이다. 왜 이런 상황이 발생했을까?

  1. 단순히 디버깅 정보 표시 잘못이다. m_nDTB는 0x0000000000185000으로 사용된다.
  2. 컴파일 시 무언가 잘못되었다.

1번인지 알고 release 모드로 실행했지만 m_nDTB가 쓰레기 값으로 사용되는 것을 확인하였다. 그럼 2번인데… 컴파일러가 왜 이걸 햇갈렸을까 아무리 생각해봤자 답이 안나오니…

컴파일러야 햇갈리지마 T^T 라는 생각으로 메모리 정렬 단위를 명시해주었다.

#pragma pack(4)

적어주니 아래와 같이 값이 컴파일러는 잘 판단해주었다. ㅡㅡ...

 

32비트 컴파일 시 기본 컴파일 단위가 4바이트라고 알고 있는데… 무엇이 잘못되었을까….

결론 : VC 2010 버전에서는 메모리 정렬 단위 선언으로 컴파일러에 확실히 명시해주자

   

'디버깅' 카테고리의 다른 글

MS 심볼 구성에 관하여  (0) 2014.12.17
Windows 10 _KPCR and _KPRCB  (0) 2014.11.14
Windbg에서 KDBG 찾기  (0) 2014.06.19
Window8 Remote Kernel Debugging on Vmware using WinDbg  (0) 2014.04.11
_DRIVER_OBJECT.DriverSection 정보  (0) 2013.10.05

wofstream을 사용하여 로그를 기록하는데 이상하게 한글만 출력이 안되었다. 입력 버퍼에도 잘 기록되었는데 안되다니 뭔가 이상했다. 출력된 로그 파일을 보니 영문과 숫자까지만 출력이 되고 그 뒤로 출력되어야할 한글 문자열부터 출력이 되지 않았다. 궁금해서 헥스 편집기로 열어서 보니 아래와 같이 아스키코드로 저장되어 있는 것을 확인할 수 있었다.

   

   

이 무슨 어이없는 일이란 말인가? wofstream으로 출력했으니 당연히 wide 문자로 나와야한다고 생각했는데 큰 오산이었다. 뭐 결국에 해결하고 생각해보면 당연한게 wofstream은 wchar_t 형태의 문자열을 파일로 출력하는 클래스기 때문에 파일 최적화를 위해서 굳이 wchar_t 형태로 내보낼 필요가 없다는 것이다.

wofstream에서 한글 출력을 설정하기 위해서는 코드에 간단하게

   

std::locale::global(std::locale("Korean"));

   

를 추가하면 된다. 하지만 코드의 어디다 넣어야 될까? 파일 쓰기 함수 전에? 파일 오픈 전에? 답은 wofstream의 인스턴스가 생성되기 전이다. (이거 떄문에 시간을 얼마나 소비했는지…) 아래는 이를 증명하는 코드이다.

   

   

코드에 적혀있는데로 wofstream은 인스턴스가 생성될 때 locale이 설정된다. 이 설정된 locale은 이후에 locale이 변경되어도 생성된 wofstream에 그대로 유지된다. 아마도 스트림별 다양한 locale을 지원하기 위해 이렇게 했나 싶다. 뭐.. 이것도 생각해보면 당연하지만…

코드는 locale 설정 전에 메모리에 할당된 스트림과 설정 후에 메모리에 할당된 스트림을 사용하여 파일에 한글 출력을 테스트한다. 위 코드를 컴파일 후 실행해보면 아래와 같이 locale 설정 전에 할당된 wofstream은 0kb로 한글을 출력하지 못한다.

   

   

이렇게 해결 방법을 알아도 문제가 되는 경우가 있는데 전역 변수(정적 변수)의 경우 locale 설정보다 먼저 메모리에 할당될 수 있다. 어쨌든 문제는 해결했으니 … bye!

   

이번 포스트 요약

wofstream은 기본 설정 사용시 wchar_t 형태의 파일 출력을 보장하지 않는다.

wofstream 인스턴스 생성 전, 즉 메모리에 할당되기 전에 locale 설정을 해야한다.

   

코드

int _tmain(int argc, _TCHAR* argv[])

{

/*

wofstream은 메모리에 할당될 때 locale이 설정된다.

이 설정된 locale은 이후에 locale이 변경되어도 유지된다.

*/

std::wofstream fstream_locale_before;

std::locale::global(std::locale("Korean"));

std::wofstream fstream_locale_after;

   

fstream_locale_before.open( _T("..\\test before locale setting.txt") );

fstream_locale_before << _T("한글 파일 출력 테스트") << std::endl;

fstream_locale_before.close();

   

fstream_locale_after.open( _T("..\\test after locale setting.txt") );

fstream_locale_after << _T("한글 파일 출력 테스트") << std::endl;

fstream_locale_after.close();

   

return 0;

}

   

'프로그래밍' 카테고리의 다른 글

Rstudio 3.3.0 스케일링 문제  (0) 2016.05.06
드라이버 개발 삽질 #1  (0) 2015.03.12
ifstream 64  (0) 2014.09.25
CPP 벡터 반복문 중 원소 지우기  (0) 2014.09.22
가상 함수 테스트  (0) 2014.07.05