Microsoftã¯ã.NET Coreã®éèŠãªèŠçŽ ã§ããCoreCLRãšã³ãžã³ã®ãœãŒã¹ã³ãŒããå ¬éããŸããã ãã¡ããããã®ãã¥ãŒã¹ã¯ç§ãã¡ã®æ³šæãåŒãããšãã§ããŸããã§ããã å®éããããžã§ã¯ãã®èŽè¡ãå€ãã»ã©ãçºèŠãããçãããå ŽæãããèŠæãããŸãã äž»èŠãªãããžã§ã¯ãã®ããã«ãMicrosoftã®èè ã§ããã«ãããããããèŠããèãããããããšããããŸãã
ã¯ããã«
CoreCLRã¯ãã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãæçµçãªãã·ã³ã³ãŒããžã®ã³ã³ãã€ã«ãªã©ã®æ©èœãå®è¡ãã.NET Coreã©ã³ã¿ã€ã ã§ãã .Net Coreã¯.Netã®ã¢ãžã¥ã©ãŒå®è£ ã§ãããèšå€§ãªæ°ã®ã·ããªãªã®ããŒã¹ãšããŠäœ¿çšã§ããŸãã
ãœãŒã¹ã³ãŒãã¯æè¿GitHubã§å©çšå¯èœã«ãªãã PVS-Studio 5.23ã䜿çšããŠãã¹ããããŸããã ç§ãšåãããã«ãMicrosoft Visual Studio Community Editionã䜿çšããŠèª°ã§ãå®å šãªæ€èšŒãã°ãååŸã§ããŸãããã®åºåãMicrosoftããã®æè¿ã®ãã¥ãŒã¹ã§ããã
ã¿ã€ããã¹
äŒçµ±çã«ãç§ã¯ã¿ã€ããã¹ã®ãããªå Žæããå§ããŸãã æ¡ä»¶åŒã§ã¯ãå€æ°ãå®æ°ããã¯ãããŸãã¯æ§é /ã¯ã©ã¹ã®ãã£ãŒã«ããç¹°ãè¿ãããŸãã ãšã©ãŒã®ååšã¯è°è«ã®åé¡ã§ããããã®ãããªå Žæã¯çºèŠãããŠãããçãããããã§ãã
V501 ã||ãã®å·ŠåŽãšå³åŽã«åäžã®ãµãåŒãtree-> gtOper == GT_CLS_VARãããããŸã æŒç®åã ClrJit lsra.cpp 3140
// register variable GTNODE(GT_REG_VAR , "regVar" ,0,GTK_LEAF|GTK_LOCAL) // static data member GTNODE(GT_CLS_VAR , "clsVar" ,0,GTK_LEAF) // static data member address GTNODE(GT_CLS_VAR_ADDR , "&clsVar" ,0,GTK_LEAF) .... void LinearScan::buildRefPositionsForNode(GenTree *tree, ....) { .... if ((tree->gtOper == GT_CLS_VAR || tree->gtOper == GT_CLS_VAR) && i == 1) { registerType = TYP_PTR; currCandidates = allRegs(TYP_PTR); } .... }
ãGenTreeãæ§é ã®ãã£ãŒã«ãåã¯ãtree-> gtTypeããšäŒŒãŠããŸããããtree-> gtOperããšã¯ç°ãªãã¿ã€ãã§ãã ããã§ã®ãã€ã³ãã¯ã³ããŒãããå®æ°ã«ãããšæããŸãã ã€ãŸããGT_CLS_VARã«å ããŠãå¥ã®å®æ°ãåŒã§äœ¿çšããå¿ èŠããããŸãã
V501 ã|ãã®å·Šãšå³ã«åãå¯æ¬¡åŒãDECODE_PSP_SYMãããããŸã æŒç®åã daccess 264
enum GcInfoDecoderFlags { DECODE_SECURITY_OBJECT = 0x01, DECODE_CODE_LENGTH = 0x02, DECODE_VARARG = 0x04, DECODE_INTERRUPTIBILITY = 0x08, DECODE_GC_LIFETIMES = 0x10, DECODE_NO_VALIDATION = 0x20, DECODE_PSP_SYM = 0x40, DECODE_GENERICS_INST_CONTEXT = 0x80, DECODE_GS_COOKIE = 0x100, DECODE_FOR_RANGES_CALLBACK = 0x200, DECODE_PROLOG_LENGTH = 0x400, DECODE_EDIT_AND_CONTINUE = 0x800, }; size_t GCDump::DumpGCTable(PTR_CBYTE table, ....) { GcInfoDecoder hdrdecoder(table, (GcInfoDecoderFlags)( DECODE_SECURITY_OBJECT | DECODE_GS_COOKIE | DECODE_CODE_LENGTH | DECODE_PSP_SYM //<==1 | DECODE_VARARG | DECODE_PSP_SYM //<==1 | DECODE_GENERICS_INST_CONTEXT //<==2 | DECODE_GC_LIFETIMES | DECODE_GENERICS_INST_CONTEXT //<==2 | DECODE_PROLOG_LENGTH), 0); .... }
ãGcInfoDecoderFlagsãåæã«ã¯æ¡ä»¶ã§äœ¿çšãããªãä»ã®å®æ°ããããŸããã2ã€ã®ç¹°ãè¿ãå®æ°ããããŸãã
åæ§ã®å ŽæïŒ
- V501ã==ãæŒç®åã®å·ŠåŽãšå³åŽã«åäžã®å¯æ¬¡åŒãvarLoc1.vlStk2.vls2BaseRegãããããŸãã cee_wks util.cpp 657
- V501ã==ãæŒç®åã®å·ŠåŽãšå³åŽã«ã¯ãåäžã®ãµãåŒãvarLoc1.vlStk2.vls2OffsetãããããŸãã cee_wks util.cpp 658
- V501ã==ãæŒç®åã®å·ŠåŽãšå³åŽã«ã¯ãåäžã®ãµãåŒãvarLoc1.vlFPstk.vlfRegãããããŸãã cee_wks util.cpp 661
V700 ãT foo = foo = ...ãåŒã®æ€æ»ãæ€èšããŠãã ããã å€æ°ãããèªäœã§åæåãããã®ã¯å¥åŠã§ãã cee_wks zapsig.cpp 172
BOOL ZapSig::GetSignatureForTypeHandle(....) { .... CorElementType elemType = elemType = TryEncodeUsingShortcut(pMT); .... }
ããã¯åãªãäžå¿ èŠãªå²ãåœãŠã®ããã«èŠããŸãããã³ãŒããã³ããŒããŠååãå€æŽããã®ãå¿ãããšããã®ãããªãšã©ãŒãããçºçããŸãã ãããã«ããŠãããã®åœ¢åŒã§ã¯ãã³ãŒãã¯ç¡æå³ã§ãã
V523 ãthenãã¹ããŒãã¡ã³ãã¯ãelseãã¹ããŒãã¡ã³ããšåçã§ãã cee_wks threadsuspend.cpp 2468
enum __MIDL___MIDL_itf_mscoree_0000_0004_0001 { OPR_ThreadAbort = 0, OPR_ThreadRudeAbortInNonCriticalRegion = .... , OPR_ThreadRudeAbortInCriticalRegion = ....) , OPR_AppDomainUnload = .... , OPR_AppDomainRudeUnload = ( OPR_AppDomainUnload + 1 ) , OPR_ProcessExit = ( OPR_AppDomainRudeUnload + 1 ) , OPR_FinalizerRun = ( OPR_ProcessExit + 1 ) , MaxClrOperation = ( OPR_FinalizerRun + 1 ) } EClrOperation; void Thread::SetRudeAbortEndTimeFromEEPolicy() { LIMITED_METHOD_CONTRACT; DWORD timeout; if (HasLockInCurrentDomain()) { timeout = GetEEPolicy()-> GetTimeout(OPR_ThreadRudeAbortInCriticalRegion); //<== } else { timeout = GetEEPolicy()-> GetTimeout(OPR_ThreadRudeAbortInCriticalRegion); //<== } .... }
ãã®èšºæã¯ãif / elseæ§é å ã§åããããã¯ãèŠã€ããŸãã ãããŠãããã§ããå®æ°ã«ã¿ã€ããã¹ã®çãããããŸãã æåã®ã±ãŒã¹ã§ã¯ãããæå³ã§ããOPR_ThreadRudeAbortInNonCriticalRegionããé©åã§ãã
åæ§ã®å ŽæïŒ
- V523ãthenãã¹ããŒãã¡ã³ãã¯ãelseãã¹ããŒãã¡ã³ããšåçã§ãã ClrJit instr.cpp 3427
- V523ãthenãã¹ããŒãã¡ã³ãã¯ãelseãã¹ããŒãã¡ã³ããšåçã§ãã ClrJit flowgraph.cpp 18815
- V523ãthenãã¹ããŒãã¡ã³ãã¯ãelseãã¹ããŒãã¡ã³ããšåçã§ãã daccess dacdbiimpl.cpp 6374
ã³ã³ã¹ãã©ã¯ã¿ãŒåæåãªã¹ã
V670åæåãããŠããªãã¯ã©ã¹ã¡ã³ã㌠'gcInfo'ã¯ã 'regSet'ã¡ã³ããŒãåæåããããã«äœ¿çšãããŸãã ã¡ã³ããŒã¯ãã¯ã©ã¹å ã®å®£èšã®é åºã§åæåãããããšã«æ³šæããŠãã ããã ClrJit codegencommon.cpp 92
CodeGenInterface *getCodeGenerator(Compiler *comp); class CodeGenInterface { friend class emitter; public: .... RegSet regSet; //<=== line 91 .... public: GCInfo gcInfo; //<=== line 322 .... }; // CodeGen constructor CodeGenInterface::CodeGenInterface(Compiler* theCompiler) : compiler(theCompiler), gcInfo(theCompiler), regSet(theCompiler, gcInfo) { }
æšæºã«åŸã£ãŠãã³ã³ã¹ãã©ã¯ã¿ãŒå ã®ã¯ã©ã¹ã¡ã³ããŒã®åæåã®é åºã¯ãã¯ã©ã¹å ã®å®£èšã®é åºã§çºçããŸãã ãšã©ãŒãä¿®æ£ããã«ã¯ãã¯ã©ã¹ãgcInfoãã®ã¡ã³ããŒã®å®£èšããregSetãã®å®£èšã®äžã«ç§»åããå¿ èŠããããŸãã
åœã ãæçšãªèŠå
V705ãelseããããã¯ãå¿ããããŠãããã³ã¡ã³ãã¢ãŠããããŠããå¯èœæ§ãããããã®ããããã°ã©ã ã®åäœããžãã¯ãå€æŽãããŠããŸãã daccess daccess.cpp 2979
HRESULT Initialize() { if (hdr.dwSig == sig) { m_rw = eRO; m_MiniMetaDataBuffSizeMax = hdr.dwTotalSize; hr = S_OK; } else // when the DAC initializes this for the case where the target is // (a) a live process, or (b) a full dump, buff will point to a // zero initialized memory region (allocated w/ VirtualAlloc) if (hdr.dwSig == 0 && hdr.dwTotalSize == 0 && hdr.dwCntStreams == 0) { hr = S_OK; } // otherwise we may have some memory corruption. treat this as // a liveprocess/full dump else { hr = S_FALSE; } .... }
ã¢ãã©ã€ã¶ãŒã¯ãã³ãŒãå ã®çãããå Žæãæ€åºããŸããã ããã§ã¯ãã³ãŒããã³ã¡ã³ãåãããŠããããã¹ãŠãæ£åžžã§ããããšãããããŸãã ãããããã®ã¿ã€ãã®ãšã©ãŒã¯ããelseãã®åŸã®ã³ãŒããã³ã¡ã³ãåãããããã«ç¶ãã¹ããŒãã¡ã³ããæ¡ä»¶ã®äžéšã«ãªãå Žåã«éåžžã«äžè¬çã§ãã ãã®äŸã§ã¯ããšã©ãŒã¯ãããŸããããå°æ¥ãã®å Žæãç·šéããå Žåã¯ããªã蚱容ã§ããŸãã
64ããããšã©ãŒ
V673 ã0xefefefef << 28ãåŒã¯1080581331517177856ã«è©äŸ¡ãããŸããå€ãä¿åããã«ã¯60ããããå¿ èŠã§ãããåŒã¯ã32ããããã®ã¿ãä¿æã§ããã笊å·ãªããã¿ã€ãã«è©äŸ¡ãããŸãã cee_dac _dac object.inl 95
inline void Object::EnumMemoryRegions(void) { .... SIZE_T size = sizeof(ObjHeader) + sizeof(Object); .... size |= 0xefefefef << 28; .... }
ã64ããããšã©ãŒããšããçšèªã«ã€ããŠã¯ã ãã¡ããã芧ãã ãã ã ãã®äŸã§ã¯ãã·ããåŸã32ãããããã°ã©ã ã§ã¯ãsize | = 0xf0000000ãã64ãããããã°ã©ã ã§ã¯ãsize | = 0x00000000f0000000ãã®æŒç®ãå®è¡ãããŸãã ã»ãšãã©ã®å Žåã64ãããããã°ã©ã ã§ã¯ãããµã€ãº| = 0x0efefefef0000000ãã®èšç®ãèšç»ããŠããŸããã ããããæ°åã®å€ãéšåã¯ã©ãã§å€±ãããŸããïŒ
æ°å€ã0xefefefefãã¯ãunsignedãã¿ã€ãã§ããããã¯ãintãã¿ã€ãã«é©åããªãããã§ãã 32ãããã®æ°å€ãã·ããããããã®çµæã笊å·ãªãåã®0xf0000000ãååŸãããŸãã ããã«ããã®ç¬Šå·ãªãã®æ°å€ã¯SIZE_Tã«æ¡åŒµããã0x00000000f0000000ãåŸãããŸãã
æ£ããåäœãããã«ã¯ããŸãæ瀺çãªåå€æãå®è¡ããå¿ èŠããããŸãã æ£ããã³ãŒãã®äŸïŒ
inline void Object::EnumMemoryRegions(void) { .... SIZE_T size = sizeof(ObjHeader) + sizeof(Object); .... size |= SIZE_T(0xefefefef) << 28; .... }
ãã®ãããªå¥ã®å ŽæïŒ
- V673ã0xefefefef << 28ãåŒã¯1080581331517177856ã«è©äŸ¡ãããŸããå€ãä¿åããã«ã¯60ããããå¿ èŠã§ãããåŒã¯ã32ããããã®ã¿ãä¿æã§ããã笊å·ãªããã¿ã€ãã«è©äŸ¡ãããŸãã cee_dac dynamicmethod.cpp 807
å»æ¢ã³ãŒã
æ¡ä»¶ã¯ãæåéãäºãã«ççŸããããã«èšè¿°ãããå ŽåããããŸãã
V637å察ã®2ã€ã®æ¡ä»¶ãçºçããŸããã 2çªç®ã®æ¡ä»¶ã¯åžžã«falseã§ãã è¡ã確èªããŠãã ããïŒ31825ã31827ãcee_wks gc.cpp 31825
void gc_heap::verify_heap (BOOL begin_gc_p) { .... if (brick_table [curr_brick] < 0) { if (brick_table [curr_brick] == 0) { dprintf(3, ("curr_brick %Ix for object %Ix set to 0", curr_brick, (size_t)curr_object)); FATAL_GC_ERROR(); } .... } .... }
å¶åŸ¡ãåŸãããšã¯ãªããã次ã®äŸã»ã©éèŠã§ã¯ãªãã³ãŒãïŒ
V517 ãifïŒAïŒ{...} else ifïŒAïŒ{...}ããã¿ãŒã³ã®äœ¿çšãæ€åºãããŸããã è«çãšã©ãŒãååšããå¯èœæ§ããããŸãã è¡ã確èªããŠãã ããïŒ2353ã2391ãutilcode util.cpp 2353
void PutIA64Imm22(UINT64 * pBundle, UINT32 slot, INT32 imm22) { if (slot == 0) { const UINT64 mask0 = UI64(0xFFFFFC000603FFFF); /* Clear all bits used as part of the imm22 */ pBundle[0] &= mask0; UINT64 temp0; temp0 = (UINT64) (imm22 & 0x200000) << 20; // 1 s temp0 |= (UINT64) (imm22 & 0x1F0000) << 11; // 5 imm5c temp0 |= (UINT64) (imm22 & 0x00FF80) << 25; // 9 imm9d temp0 |= (UINT64) (imm22 & 0x00007F) << 18; // 7 imm7b /* Or in the new bits used in the imm22 */ pBundle[0] |= temp0; } else if (slot == 1) { .... } else if (slot == 0) //<== { const UINT64 mask1 = UI64(0xF000180FFFFFFFFF); /* Clear all bits used as part of the imm22 */ pBundle[1] &= mask1; UINT64 temp1; temp1 = (UINT64) (imm22 & 0x200000) << 37; // 1 s temp1 |= (UINT64) (imm22 & 0x1F0000) << 32; // 5 imm5c temp1 |= (UINT64) (imm22 & 0x00FF80) << 43; // 9 imm9d temp1 |= (UINT64) (imm22 & 0x00007F) << 36; // 7 imm7b /* Or in the new bits used in the imm22 */ pBundle[1] |= temp1; } FlushInstructionCache(GetCurrentProcess(),pBundle,16); }
ãããããéåžžã«éèŠãªã³ãŒãã¯ãæ¡ä»¶ä»ãã¹ããŒãã¡ã³ãã®ã«ã¹ã±ãŒãã®ãšã©ãŒã®ããã«å¶åŸ¡ãããŸããã
ããäžå¯©ãªå ŽæïŒ
- V637å察ã®2ã€ã®æ¡ä»¶ãçºçããŸããã 2çªç®ã®æ¡ä»¶ã¯åžžã«falseã§ãã è¡ã確èªããŠãã ããïŒ2898ã2900ãdaccess nidump.cpp 2898
- V637å察ã®2ã€ã®æ¡ä»¶ãçºçããŸããã 2çªç®ã®æ¡ä»¶ã¯åžžã«falseã§ãã è¡ã確èªããŠãã ããïŒ337ã339ãutilcode prettyprintsig.cpp 337
- V637å察ã®2ã€ã®æ¡ä»¶ãçºçããŸããã 2çªç®ã®æ¡ä»¶ã¯åžžã«falseã§ãã è¡ã確èªããŠãã ããïŒ774ã776ãutilcode prettyprintsig.cpp 774
æªå®çŸ©ã®åäœ
V610æªå®çŸ©ã®åäœã ã·ããæŒç®åã<<ãã確èªããŠãã ããã å·Šã®ãªãã©ã³ã '-1'ã¯è² ã§ãã bcltype metamodel.h 532
inline static mdToken decodeToken(....) { //<TODO>@FUTURE: make compile-time calculation</TODO> ULONG32 ix = (ULONG32)(val & ~(-1 << m_cb[cTokens])); if (ix >= cTokens) return rTokens[0]; return TokenFromRid(val >> m_cb[cTokens], rTokens[ix]); }
ã¢ãã©ã€ã¶ãŒã¯ãæªå®çŸ©ã®åäœã«ã€ãªããè² ã®æ°å€ã·ããæäœãæ€åºããŸããã
V610æªå®çŸ©ã®åäœã ã·ããæŒç®åã<<ãã確èªããŠãã ããã å·Šã®ãªãã©ã³ã 'ïŒã0ïŒ'ã¯è² ã§ãã cee_dac decodemd.cpp 456
#define bits_generation 2 #define generation_mask (~(~0 << bits_generation)) #define MASK(len) (~((~0)<<len)) #define MASK64(len) ((~((~((unsigned __int64)0))<<len))) void Encoder::Add(unsigned value, unsigned length) { .... value = (value & MASK(length)); .... }
V610ã¢ãã©ã€ã¶ãŒããã®ã¡ãã»ãŒãžã®ãããã§ãããã€ãã®èª€ã£ããã¯ããèŠã€ãããŸããã 'ã0'ã¯ãintåã®ç¬Šå·ä»ãè² ã®æ°ã«ãã£ã¹ãããããã®åŸã·ãããå®è¡ãããŸãã ãã¯ãã®1ã€ãšåæ§ã«ã笊å·ãªããžã®æ瀺çãªå€æãå®è¡ããå¿ èŠããããŸãã
#define bits_generation 2 #define generation_mask (~(~((unsigned int)0) << bits_generation)) #define MASK(len) (~((~((unsigned int)0))<<len)) #define MASK64(len) ((~((~((unsigned __int64)0))<<len)))
ç¡å¹ãªãµã€ãºïŒxxïŒ
V579 DacReadAllé¢æ°ã¯ããã€ã³ã¿ãŒãšãã®ãµã€ãºãåŒæ°ãšããŠåãåããŸãã ééããããããŸããã 3çªç®ã®åŒæ°ã調ã¹ãŸãã daccess dacimpl.h 1688
template<class T> inline bool MisalignedRead(CORDB_ADDRESS addr, T *t) { return SUCCEEDED(DacReadAll(TO_TADDR(addr), t, sizeof(t), false)); }
ããã¯ãåžžã«ãã€ã³ã¿ãŒã®ãµã€ãºããšãå°ããªé¢æ°ã§ãã ã»ãšãã©ã®å ŽåããsizeofïŒ* tïŒãããŸãã¯ãsizeofïŒTïŒããèšè¿°ããããšèããŠããŸããã
å¥ã®å®äŸïŒ
V579èªã¿åãé¢æ°ã¯ããã€ã³ã¿ãŒãšãã®ãµã€ãºãåŒæ°ãšããŠåãåããŸãã ééããããããŸããã 3çªç®ã®åŒæ°ã調ã¹ãŸãã util.cpp 4943
HRESULT GetMTOfObject(TADDR obj, TADDR *mt) { if (!mt) return E_POINTER; HRESULT hr = rvCache->Read(obj, mt, sizeof(mt), NULL); if (SUCCEEDED(hr)) *mt &= ~3; return hr; }
MemFAILãã¡ããªãŒã®æ©èœ
memXXXé¢æ°ã䜿çšãããšãããŸããŸãªãšã©ãŒãçºçããå¯èœæ§ããããŸãã ã¢ãã©ã€ã¶ãŒã§ãã®ãããªå Žæãæ€çŽ¢ããã«ã¯ãããã€ãã®èšºæã«ãŒã«ããããŸãã
V512 ãmemsetãé¢æ°ã®åŒã³åºãã«ããããããã¡ãŒãpAddExpressionãã®ã¢ã³ããŒãããŒãçºçããŸãã sos strike.cpp 11973
DECLARE_API(Watch) { .... if(addExpression.data != NULL || aExpression.data != NULL) { WCHAR pAddExpression[MAX_EXPRESSION]; memset(pAddExpression, 0, MAX_EXPRESSION); swprintf_s(pAddExpression, MAX_EXPRESSION, L"%S", ....); Status = g_watchCmd.Add(pAddExpression); } .... }
ãµã€ãºã¿ã€ãã®èª¿æŽãå¿ããå Žåã®ããããééãïŒ
WCHAR pAddExpression[MAX_EXPRESSION]; memset(pAddExpression, 0, sizeof(WCHAR)*MAX_EXPRESSION);
ããã«ããã€ãã®ãã®ãããªå ŽæïŒ
- V512ãmemsetãé¢æ°ã®åŒã³åºãã«ããããããã¡ãŒãpSaveNameãã®ã¢ã³ããŒãããŒãçºçããŸãã sos strike.cpp 11997
- V512ãmemsetãé¢æ°ã®åŒã³åºãã«ããããããã¡ãŒãpOldNameãã®ã¢ã³ããŒãããŒãçºçããŸãã sos strike.cpp 12013
- V512ãmemsetãé¢æ°ã®åŒã³åºãã«ããããããã¡ãŒãpNewNameãã®ã¢ã³ããŒãããŒãçºçããŸãã sos strike.cpp 12016
- V512ãmemsetãé¢æ°ãåŒã³åºããšããããã¡ãŒãpExpressionãã®ã¢ã³ããŒãããŒãçºçããŸãã sos strike.cpp 12024
- V512ãmemsetãé¢æ°ãåŒã³åºããšããããã¡ãŒãpFilterNameãã®ã¢ã³ããŒãããŒãçºçããŸãã sos strike.cpp 12039
V598 ãmemcpyãé¢æ°ã¯ããGenTreeãã¯ã©ã¹ã®ãã£ãŒã«ããã³ããŒããããã«äœ¿çšãããŸãã ããã«ãããä»®æ³ããŒãã«ãã€ã³ã¿ãŒãç ŽæããŸãã ClrJit compiler.hpp 1344
struct GenTree { .... #if DEBUGGABLE_GENTREE virtual void DummyVirt() {} #endif // DEBUGGABLE_GENTREE .... }; void GenTree::CopyFrom(const GenTree* src, Compiler* comp) { .... memcpy(this, src, src->GetNodeSize()); .... }
ããªããã»ããµå€æ°ãDEBUGGABLE_GENTREEãã宣èšãããŠããå Žåãä»®æ³é¢æ°ãå®çŸ©ãããŸãã 次ã«ãã¯ã©ã¹ã«ã¯ä»®æ³ã¡ãœããã®ããŒãã«ãžã®ãã€ã³ã¿ãå«ãŸãããã®ããã«ã³ããŒããããšã¯ã§ããªããªããŸãã
V598 ãmemcpyãé¢æ°ã¯ããGCStatisticsãã¯ã©ã¹ã®ãã£ãŒã«ããã³ããŒããããã«äœ¿çšãããŸãã ããã«ãããä»®æ³ããŒãã«ãã€ã³ã¿ãŒãç ŽæããŸãã cee_wks gc.cpp 287
struct GCStatistics : public StatisticsBase { .... virtual void Initialize(); virtual void DisplayAndUpdate(); .... }; GCStatistics g_LastGCStatistics; void GCStatistics::DisplayAndUpdate() { .... memcpy(&g_LastGCStatistics, this, sizeof(g_LastGCStatistics)); .... }
ãã®å Žæã§ã¯ããããã°ã¢ãŒãã ãã§ãªãã誀ã£ãã³ããŒãå®è¡ãããŸãã
V698åŒ 'memcmpïŒ....ïŒ== -1'ã¯æ£ãããããŸããã ãã®é¢æ°ã¯ãå€ '-1'ã ãã§ãªããè² ã®å€ãè¿ãããšãã§ããŸãã 代ããã« 'memcmpïŒ....ïŒ<0'ã®äœ¿çšãæ€èšããŠãã ããã sos util.cpp 142
bool operator( )(const GUID& _Key1, const GUID& _Key2) const { return memcmp(&_Key1, &_Key2, sizeof(GUID)) == -1; }
'memcmp'é¢æ°ã®çµæã1ãŸãã¯-1ã®å€ãšæ¯èŒããããšã¯æ£ãããããŸããã ãã®ãããªæ§é ã®æäœæ§ã¯ãã©ã€ãã©ãªãã³ã³ãã€ã©ããã®èšå®ããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ããã®å®¹éãªã©ã«äŸåããŸãã ãã®å Žåãã<0ããã0ããŸãã¯ã> 0ãã®3ã€ã®ç¶æ ã®ããããã確èªããå¿ èŠããããŸãã
åæ§ã®å ŽæïŒ
- V698åŒ 'wcscmpïŒ....ïŒ== -1'ã¯æ£ãããããŸããã ãã®é¢æ°ã¯ãå€ '-1'ã ãã§ãªããè² ã®å€ãè¿ãããšãã§ããŸãã 代ããã«ãwcscmpïŒ....ïŒ<0ãã䜿çšããããšãæ€èšããŠãã ããã sos strike.cpp 3855
ãã€ã³ã¿ãŒã«ã€ããŠ
V522ãã«ãã€ã³ã¿ãŒãhpãã®éåç §ãè¡ãããå ŽåããããŸãã cee_wks gc.cpp 4488
heap_segment* gc_heap::get_segment_for_loh (size_t size #ifdef MULTIPLE_HEAPS , gc_heap* hp #endif //MULTIPLE_HEAPS ) { #ifndef MULTIPLE_HEAPS gc_heap* hp = 0; #endif //MULTIPLE_HEAPS heap_segment* res = hp->get_segment (size, TRUE); .... }
ãMULTIPLE_HEAPSããå®çŸ©ãããŠããªãå Žåããã©ãã«ãçºçããŸãã ãã€ã³ã¿ãŒã¯ãŒãã«ãªããŸãã
V595 nullptrã«å¯ŸããŠæ€èšŒãããåã«ããããªãŒããã€ã³ã¿ãŒã䜿çšãããŸããã è¡ã確èªããŠãã ããïŒ6970ã6976ãClrJit gentree.cpp 6970
void Compiler::gtDispNode(GenTreePtr tree, ....) { .... if (tree->gtOper >= GT_COUNT) { printf(" **** ILLEGAL NODE ****"); return; } if (tree && printFlags) { /* First print the flags associated with the node */ switch (tree->gtOper) { .... } .... } .... }
ãã€ã³ã¿ãŒã®æå¹æ§ããã§ãã¯ããããšãããã ãåç §è§£é€åŸã«ãœãŒã¹ã³ãŒãã«å ŽæããããŸãã
ãªã¹ãå šäœïŒ CoreCLR_V595.txt
è¿œå ã®ãã§ãã¯
äœåãªã³ãŒããæ害ã§ã¯ãªãå Žåã§ãããã®ååšã¯éçºã®æ³šæãããéèŠãªå Žæããåã«ãããããšãã§ããŸãã
V503ããã¯ç¡æå³ãªæ¯èŒã§ãïŒpointer> =0ãcee_wks gc.cpp 21707
void gc_heap::make_free_list_in_brick (BYTE* tree, make_free_args* args) { assert ((tree >= 0)); .... }
ããããã€ã³ã¿ãŒãã§ãã¯ã§ãã ãã®ä»ã®äŸïŒ
- V503ããã¯ç¡æå³ãªæ¯èŒã§ãïŒpointer> =0ãcee_wks gc.cpp 23204
- V503ããã¯ç¡æå³ãªæ¯èŒã§ãïŒpointer> =0ãcee_wks gc.cpp 27683
V547åŒ 'maxCpuId> = 0'ã¯åžžã«trueã§ãã 笊å·ãªãã®åã®å€ã¯åžžã«> = 0ã§ããcee_wks codeman.cpp 1219
void EEJitManager::SetCpuInfo() { .... unsigned char buffer[16]; DWORD maxCpuId = getcpuid(0, buffer); if (maxCpuId >= 0) { .... }
DWORDã¿ã€ãã®ã¿ã䜿çšããåæ§ã®äŸã
V590 'wzPath [0]ïŒ= L' \ 0 '&& wzPath [0] == L' \\ ''åŒã®æ€æ»ãæ€èšããŠãã ããã è¡šçŸãéå°ã§ãããã誀æ€ãå«ãŸããŠããŸãã cee_wks path.h 62
static inline bool HasUncPrefix(LPCWSTR wzPath) { _ASSERTE(!clr::str::IsNullOrEmpty(wzPath)); return wzPath[0] != W('\0') && wzPath[0] == W('\\') && wzPath[1] != W('\0') && wzPath[1] == W('\\') && wzPath[2] != W('\0') && wzPath[2] != W('?'); }
ãã®æ©èœã¯ã次ã®ãªãã·ã§ã³ã«ç°¡ç¥åã§ããŸãã
static inline bool HasUncPrefix(LPCWSTR wzPath) { _ASSERTE(!clr::str::IsNullOrEmpty(wzPath)); return wzPath[0] == W('\\') && wzPath[1] == W('\\') && wzPath[2] != W('\0') && wzPath[2] != W('?'); }
ãã®ãããªå¥ã®å ŽæïŒ
- V590ãã®è¡šçŸã調ã¹ãããšãæ€èšããŠãã ããã è¡šçŸãéå°ã§ãããã誀æ€ãå«ãŸããŠããŸãã cee_wks path.h 72
V571å®æçãªãã§ãã¯ã ãifïŒmoduleInfo [MSCORWKS] .baseAddr == 0ïŒãæ¡ä»¶ã¯ã749è¡ç®ã§æ¢ã«æ€èšŒãããŠããŸããsos util.cpp 751
struct ModuleInfo { ULONG64 baseAddr; ULONG64 size; BOOL hasPdb; }; HRESULT CheckEEDll() { .... // Do we have clr.dll if (moduleInfo[MSCORWKS].baseAddr == 0) //<== { if (moduleInfo[MSCORWKS].baseAddr == 0) //<== g_ExtSymbols->GetModuleByModuleName ( MAIN_CLR_MODULE_NAME_A,0,NULL, &moduleInfo[MSCORWKS].baseAddr); if (moduleInfo[MSCORWKS].baseAddr != 0 && //<== moduleInfo[MSCORWKS].hasPdb == FALSE) { .... } .... } .... }
2çªç®ã®å ŽåããbaseAddrãã¯ãã§ãã¯ã§ããªããªããŸãã
V704 'this == nullptr'åŒã¯é¿ããå¿ èŠããããŸã-'this 'ãã€ã³ã¿ãŒãNULLã«ãªãããšã¯ãªãããããã®åŒã¯æ°ããã³ã³ãã€ã©ãŒã§ã¯åžžã«falseã§ãã ClrJit gentree.cpp 12731
bool FieldSeqNode::IsFirstElemFieldSeq() { if (this == nullptr) return false; return m_fieldHnd == FieldSeqStore::FirstElemPseudoField; }
C ++æšæºã«ãããšãthisãã€ã³ã¿ãŒã¯æ±ºããŠnullã«ã§ããŸããã ãã®ãããªã³ãŒãã®èããããçµæã¯ã V704蚺æã®èª¬æã«è©³çŽ°ã«èšèŒãããŠããŸãã ãã®ãããªã³ãŒããVisual C ++ã³ã³ãã€ã©ã«ããã³ã³ãã€ã«åŸã«æ£ããæ©èœãããšããäºå®ã¯å¹žéã§ãããæ£çŽã«é Œãããšã¯ã§ããŸããã
å šãªã¹ãïŒ CoreCLR_V704.txt
V668 ãnewãæŒç®åã䜿çšããŠã¡ã¢ãªãå²ãåœãŠãããããããnewChunkããã€ã³ã¿ãŒãnullã«å¯ŸããŠãã¹ãããŠãæå³ããããŸããã ã¡ã¢ãªå²ãåœãŠãšã©ãŒã®å ŽåãäŸå€ãçæãããŸãã ClrJit stresslog.h 552
FORCEINLINE BOOL GrowChunkList () { .... StressLogChunk * newChunk = new StressLogChunk (....); if (newChunk == NULL) { return FALSE; } .... }
ãnewãæŒç®åãã¡ã¢ãªãå²ãåœãŠãããªãã£ãå ŽåãC ++èšèªæšæºã«åŸã£ãŠãäŸå€std :: bad_allocïŒïŒãã¹ããŒãããŸãã ãããã£ãŠããŒãã«çããããšã瀺ããã€ã³ã¿ãŒããã§ãã¯ããããšã¯æå³ããããŸããã
ãã®ãããªå Žæã確èªããããšããå§ãããŸããå®å šãªãªã¹ãïŒ CoreCLR_V668.txtã§ãã
ãããã«
æè¿ç«ã¡äžããããCoreCLRãããžã§ã¯ãã¯ãã¯ããŒãºããœãŒã¹ãœãããŠã§ã¢ãã©ã®ããã«èŠãããã®è¯ãäŸã§ãã ãã®ãããã¯ã«ã€ããŠã¯åžžã«è°è«ãç¶ããããŠãããããã«åçãšè°è«ã®å¥ã®çç±ããããŸãã
ç§ãã¡ã«ãšã£ãŠã倧èŠæš¡ãªãããžã§ã¯ãã§ã¯äœããã®ãšã©ãŒãèŠã€ããããšãã§ããéçã¢ãã©ã€ã¶ãŒãžã®æé©ãªã¢ããªã±ãŒã·ã§ã³ã¯å®æçãªãã§ãã¯ã§ããããšãéèŠã§ãã æ ããã«PVS-StudioãããŠã³ããŒãã㊠ããããžã§ã¯ãã確èªããŠãã ããã
ãã®èšäºã¯è±èªã§ãã
è±èªã話ãèŽè¡ãšãã®èšäºãå ±æãããå Žåã¯ã翻蚳ãžã®ãªã³ã¯ã䜿çšããŠãã ããïŒSvyatoslav Razmyslovã PVS-StudioïŒCoreCLRã®25ã®çãããã³ãŒããã©ã°ã¡ã³ã ã
èšäºãèªãã§è³ªåããããŸããïŒ
å€ãã®å Žåãèšäºã«ã¯åã質åãå¯ããããŸãã ããã§ãããã«å¯ŸããåçãåéããŸããïŒ PVS-Studioããã³CppCatããŒãžã§ã³2014ã«é¢ããèšäºã®èªè
ããã®è³ªåãžã®åç ã ãªã¹ããã芧ãã ããã