ä»å¹Žãç§ãã¡ã¯é·ãéç©è°ãããããŠããããšãã€ãŸãPVS-Studio補åãLinuxã·ã¹ãã ã«é©å¿ãããããšãå§ããŸããã ãã®èšäºã§ã¯ã10幎ã«ãããPVS-Studioã¢ãã©ã€ã¶ãŒfor Windowsã®åŸãLinuxãã£ã¹ããªãã¥ãŒã·ã§ã³åãã®è£œåãã©ã®ããã«äœæãããã«ã€ããŠèª¬æããŸãã æ®å¿µãªãããäžéšã®ããã°ã©ããŒãèããããã«ãããã¯å€ãã®äœæ¥ã§ãããéå®ãããŸããããã¿ãŒã²ãããã©ãããã©ãŒã çšã®ãœãŒã¹ã³ãŒãã®ã¿ãã³ã³ãã€ã«ããŸãã
ã¯ããã«
äžè¬ã«ã
PVS-Studioã¢ãã©ã€ã¶ãŒã®ã³ã³ãœãŒã«ã«ãŒãã«ã¯é·ãéLinuxã§æ§ç¯ãããŠããŸããã çŽ3幎éã«ãªããŸãã ãããªãã¯ãã¡ã€ã³ã«ãã®ãããªããŒãžã§ã³ãååšããªããšãã質åã«ããã«çããŸããæ¢åã®ãœãããŠã§ã¢è£œåãããŒã¹ã«ãããœãããŠã§ã¢è£œåãäœæããããšã¯ã倧ããªä»äºã§ãããå€ãã®å·¥æ°ãäºæãã¬åé¡ããã¥ã¢ã³ã¹ãå€ããããŸãã 次ã«ããããäºèŠããã ããªã®ã§ãLinuxã·ã¹ãã ã®å
¬åŒã¢ãã©ã€ã¶ãŒãµããŒãã¯éå§ãããŸããã§ããã
ç§ã®ååãšã¯ç°ãªãããããžã§ã¯ãæ€èšŒã«é¢ããå€ãã®èšäºã®èè
ã§ããç§ã¯ãLinuxãããžã§ã¯ãããã€ã³ã¹ãã¬ãŒã·ã§ã³ãåŸãŸããã ãã®ç°å¢ã«ã¯ãWindowsäžã§æ§ç¯ããã®ãéåžžã«é£ããããäžå¯èœãªå€§èŠæš¡ã§èå³æ·±ããªãŒãã³ãœãŒã¹ãããžã§ã¯ããè±å¯ã«ãããŸãã ããã¯ãPVS-Studio for Linuxãä»æ¥ãŸã§ã«éçºãããªãŒãã³ãœãŒã¹ãããžã§ã¯ãããã§ãã¯ãããã®ãããªã¿ã¹ã¯ã®ãã¬ãŒã ã¯ãŒã¯å
ã«ãããŸãã
PVS-Studioã«ãŒãã«ã³ãŒããLinuxã«ç§»æ€ããã®ã«æ°ãæããããŸããã ã·ã¹ãã é¢æ°ãžã®è€æ°ã®åŒã³åºãã眮ãæããChromiumãããžã§ã¯ãã§ãããã°ããããšã«ããããã§ã«æ£åžžã«æ©èœããã³ã³ãœãŒã«ã¢ããªã±ãŒã·ã§ã³ãæäŸãããŸããã ãã®ããŒãžã§ã³ã®ã¢ãã©ã€ã¶ãŒã¯ãéåžžã®å€éãã«ãã«è¿œå ãããClang Static Analyzerã§ããã¹ããããŸããã éããŠãããããžã§ã¯ããšã¢ã»ã³ããªå¶åŸ¡ã®å®æçãªãã§ãã¯ã«ãããã¢ãã©ã€ã¶ãŒã¯æ°å¹Žéåé¡ãªãååšããæã«ã¯ãã®ããŒã«ããã§ã«è²©å£²ãããŠããããã«ããèŠããŸããã ãããããã®æç¹ã§ç§ãã©ã®ããã«ãããžã§ã¯ãããã§ãã¯ããªããã°ãªããªãã£ããã¯ãŸã ããããŸãã...
éçåæããŒã«ã®äœ¿çšã«ã€ããŠ
ããŒã«ã®éçºã«é¢ãã話ãç¶ããåã«ãéçåæã®æ¹æ³è«èªäœã«ã€ããŠå°ãã話ãããããšæããŸãã ãããã£ãŠãããšã©ãŒãªãã§ããã«ã³ãŒããèšè¿°ããååãšã¬ãã¥ãŒãè¡ãããšãã§ããå ŽåããªããµãŒãããŒãã£è£œããŒã«ã䜿çšããã®ãããšããã¹ã¿ã€ã«ã§è³ªåã«ããã«çããŸãã æ®å¿µãªããããã®è³ªåã¯ããèãããŸãã
éçã³ãŒãåæã䜿çšãããšãããã°ã©ã ã®ãœãŒã¹ã³ãŒãã®ãšã©ãŒãæ¬ èœãç¹å®ã§ããŸãã 䜿çšããããŒã«ã«é¢ä¿ãªããããã¯å°æ¥ã®ã¢ããªã±ãŒã·ã§ã³ã®ã³ãŒãã®å質管çã®ããã®åªããæ¹æ³è«ã§ãã å¯èœã§ããã°ãããŸããŸãªéç解æããŒã«ãçµã¿åããããšäŸ¿å©ã§ãã
äŒè°ã®èªè
ããŠãŒã¶ãŒããŸãã¯ãªã¹ããŒã®äžã«ã¯ãååãšã³ãŒããã¬ãã¥ãŒããã ãã§ãã³ãŒãäœæã®åæ段éã§ãšã©ãŒãç¹å®ã§ãããšèãã人ãããŸãã ãããŠããã®ãããªãæ€çŽ¢ãã§äœããããããèŠã€ããããã§ãããã ããããä»åãåãããšã«ã€ããŠè©±ããŠããã å®éãéçåæã¯ã³ãŒãã¬ãã¥ãŒã®èªååãããããã»ã¹ãšèããããšãã§ããŸãã éçã¢ãã©ã€ã¶ãŒãååã®ããäžäººã§ãããšæ³åããŠãã ããã ãã¹ãŠã®ã³ãŒãã¬ãã¥ãŒã«ç²Ÿåçã«åå ããçãããå Žæã瀺ãäžçš®ã®ä»®æ³äººéããããã ããã¯äŸ¿å©ã§ã¯ãããŸãããïŒïŒ
å€ãã®æ¥çã§ã¯ãããããã人çèŠå ããæé€ããããã«èªååã«é Œã£ãŠããŸãã ãŸããã³ãŒãå質管çãäŸå€ã§ã¯ãããŸããã æåã®ã³ãŒãã¬ãã¥ãŒãç·Žç¿ããããšãæåŠããããšã¯ãå§ãããŸããã éçã¢ãã©ã€ã¶ãŒã䜿çšããã ãã§ãåæ段éã§ããã«å€ãã®ãšã©ãŒãæ€åºã§ããŸãã
ãã1ã€ã®éèŠãªãã€ã³ã-ããã°ã©ã ã¯ç²ãããæ ãããããŸããã ããŸããŸãªçš®é¡ã®ãšã©ãŒãã³ãŒãã«å°å
¥ãããŸãã ã¿ã€ããã¹ïŒ ç®ã§åºå¥ããã®ã¯éåžžã«é£ããã§ãã èšèªãšã©ãŒïŒ 審æ»å®ã®è³æ Œã«åŒ·ãäŸåããŠããŸãã ç¶æ³ã¯ãçŸä»£ã®å€§éã®ã³ãŒãã«ãã£ãŠæªåããŠããŸãã å€ãã®æ©èœã¯ã倧åã¢ãã¿ãŒã§ãå®å
šã«ã¯åãŸããŸããã ã³ã³ããã¹ããäžå®å
šãªå Žåãæ€æ»å®ã®èŠæã¯äœäžããŸãã ããã«ã15åéã³ãŒãã泚ææ·±ãèªãã 人ã¯ç²ãå§ããŸãã ãããŠãé ããªãã»ã©åŒ·ããªããŸãã ãããã£ãŠãæ¯å¹Žå¢å ããŠããèªååæããŒã«ã®äººæ°ã
PVS-StudioãŠãŒã¶ãŒã¯LinuxããŒãžã§ã³ã«äœãæ±ããŸãããïŒ
åœç€Ÿã®è£œåã¯ãããã°ã©ã ã®éçºã«äœããã®åœ¢ã§é¢ä¿ããŠãã人ã
ã«ãšã£ãŠåžžã«èå³æ·±ããã®ã§ããã ãããã¯ãã¢ãã©ã€ã¶ãŒãããã«è©Šãããšãã§ããWindowsãŠãŒã¶ãŒã§ãã äžè¬ã®ããã°ã©ããŒã§ããä»ã®ãã©ãããã©ãŒã ãèšèªã®ããã°ã©ããŒã§ããããŸããã ãã®ãããªæ³šæãæåŸ
ãããŠããŸã å€ãã®ãšã©ãŒã¯å€ãã®ããã°ã©ãã³ã°èšèªã«å
±éããŠããŸãã
LinuxãŠãŒã¶ãŒã¯ããã®ãã©ãããã©ãŒã ã®ã¢ãã©ã€ã¶ãŒã«ã€ããŠé·ãé匷ãå°ããŠããŸããã 質åãšè°è«ã¯æ¬¡ã®ããã«èŠçŽã§ããŸãã
- ã³ãã³ãã©ã€ã³ãŠãŒãã£ãªãã£-ãIDEãšã®çµ±åã¯äžèŠã§ãïŒã
- ã€ã³ã¹ããŒã©ãŒã¯äžèŠã§ã-ããã¹ãŠãèªåã§ã€ã³ã¹ããŒã«ããŸãïŒã
- ããã¥ã¡ã³ãã¯å¿
èŠãããŸãã-ãèªåã§å®è¡ããŸãããïŒã
ãããªãã¹ããŒãªãŒã¯ããŠãŒã¶ãŒã®å£°æãšåœŒãã®æåŸ
ãšã®ççŸãç¹°ãè¿ã確èªããŸãã
ã¢ã»ã³ããªã¹ã¯ãªãããç解ãããšããç¥è©±
倧èŠæš¡ãªåæ¥ãããžã§ã¯ãã®äººã
ãšè©±ãããåŸãå€ãã®éçºè
ãããââãžã§ã¯ãã®çµã¿ç«ãŠã«ç²ŸéããŠããªãããšãå€æããŸãããå®éããã®ãããªç¥èã¯å¿
ãããå®å
šã«å¿
èŠã§ã¯ãããŸããã åéçºè
ã¯ãèªåã®ãããžã§ã¯ã/ã¢ãžã¥ãŒã«ããã«ã/ãããã°ããæ¹æ³ãç¥ã£ãŠããŸãã ããããéåžžããã®ç¥èã¯ãã¹ãŠãããã°ã©ããŒãå®è¡ããããã€ãã®éæ³ã®ã³ãã³ãã®ã»ããã§ãã æ¯urçã«èšãã°ã倧ããªãã¿ã³ããããã¯ãªãã¯ããã ãã§ååã§ãããåºåã§ã¯çµã¿ç«ãŠãããã¢ãžã¥ãŒã«ãååŸããŸãã ããããããããã¹ãŠãå
éšã§ã©ã®ããã«æ©èœãããã«ã€ããŠã¯ãäžè¬çãªèããããããŸããã ãŸããã¢ã»ã³ããªã¹ã¯ãªããã¯å€ãã®å Žåãç¹å¥ãªäººã«ãã£ãŠç£èŠãããŸãã
ãã®ãããªå Žåãå°ãªããšãã¢ãã©ã€ã¶ãŒã«æ
£ããã«ã¯ãçµ±åãªãã§ãããžã§ã¯ããæ€èšŒããããŒã«ãå¿
èŠã§ãã
ã¢ãã©ã€ã¶ãŒã®LinuxããŒãžã§ã³ã¯ãWindowsã§ã³ã³ãã€ã©ãŒç£èŠã·ã¹ãã ãäœæããçŽåŸã«è¡šç€ºããããã®ãã©ãããã©ãŒã ã§ãããžã§ã¯ãããã§ãã¯ã§ããŸããã åŸã§å€æããããã«ãMicrosoftã³ã³ãã€ã©ãŒã䜿çšããŠåéãããå€ãã®æ·±å»ãªãããžã§ã¯ãããããŸãããVisual Studioçšã®ãããžã§ã¯ãã¯ãããŸããã ããã§ãQtãFirefoxãCryEngine5ã®ãã§ãã¯ã«é¢ããèšäºãå·çããããã«Epic Games
ãšååããŠãã³ãŒãã®ãã°ãä¿®æ£ããŸããã 調æ»ã§ã¯ãã³ã³ãã€ã©ã«é¢ããæ
å ±ïŒã¹ã¿ãŒãã¢ãããã£ã¬ã¯ããªãã³ãã³ãã©ã€ã³ãã©ã¡ãŒã¿ãç°å¢å€æ°ïŒãç¥ã£ãŠããå Žåããã®æ
å ±ã§ããªããã»ããµãåŒã³åºããŠåæãå®è¡ããããšãã§ããŸãã
Linuxãããžã§ã¯ãããã§ãã¯ããèšç»ãç«ãŠãŠãããšãã«ãç¹å®ã®ãããžã§ã¯ãããšã«ã¢ãã©ã€ã¶ãŒã®çµ±åãç解ã§ããªãããšã«ããã«æ°ã¥ããã®ã§ãProcFSïŒ/ proc / id'sïŒã«åæ§ã®ç£èŠã·ã¹ãã ãäœæããŸããã Windowsãã©ã°ã€ã³ããã³ãŒããååŸããã¢ãã§å®è¡ããŠãã¡ã€ã«ãåæããŸããã æ°å¹Žã«ãããããã®æ¹æ³ã¯ãããžã§ã¯ãã®ãã¹ãã«äœ¿çšãããŠããŸãããããã®æ倧ã®ãã®ã¯
Linuxã«ãŒãã«ãš
FreeBSDã§ãã ãã®æ¹æ³ã¯é·æã«ããã£ãŠäœ¿çšãããŠããŸããã倧é䜿çšã«ã¯é©ããŠããŸããã 補åã¯ãŸã æºåãã§ããŠããŸããã
ç£èŠæè¡ã®éžæ
ãã®ãããªæ©èœã®å¿
èŠæ§ãšéèŠæ§ã決å®ããã®ã§ããããã¿ã€ããäœæããŠéžæãå§ããŸããã
- ïŒ-ïŒClang scan-build-Clang'aã¹ã¯ãªããã確èªããåŸãCC / CXXå€æ°ã§ã¢ãã©ã€ã¶ãŒåŒã³åºããåæ§ã«ç»é²ãããããã¿ã€ããäœæããŸããã ãã®æ¹æ³ã§ã¯ãClang Static Analyzerã䜿çšããŠäžéšã®éããŠãããããžã§ã¯ãããã§ãã¯ããããšãã§ããªããšããäºå®ã«çŽé¢ããŠããŸããã ãã®æ¹æ³ãããç解ããŠããããžã§ã¯ãã®ãããã®å€æ°ã«ã³ã³ãã€ã«ãã©ã°ãè¿œå ãããããšãå€ãããšã«æ°ä»ããŸããã ãŸããå€æ°ããªãŒããŒã©ã€ãããå Žåãä¿åã§ããŸããã ãã®ããããã®æ¹æ³ãæŸæ£ããŸããã
- ïŒ+ïŒstrace-ãŠãŒãã£ãªãã£ã¯ããªã詳现ãªãã¬ãŒã¹ãã°ãçæããŸãããã®ãã°ã§ã¯ããã°ã«èšé²ãããããã»ã¹ã®ã»ãšãã©ã¯ã³ã³ãã€ã«ã«é¢é£ããŠããŸããã ãŸãããã®ãŠãŒãã£ãªãã£ã®åºå圢åŒã«ã¯ãããã»ã¹ã«å¿
èŠãªäœæ¥ãã£ã¬ã¯ããªããããŸããã ããããåããã»ã¹ãšèŠªããã»ã¹ããªã³ã¯ããããšã§ãªããšããã£ã¬ã¯ããªãèŠã€ããããšãã§ããC ++ã¢ããªã±ãŒã·ã§ã³ã¯ãã®ãããªãã¡ã€ã«ãéåžžã«è¿
éã«è§£æããèŠã€ãã£ããã¡ã€ã«ã®åæã䞊è¡ããŠéå§ããŸããã ãã®ãããä»»æã®ã¢ã»ã³ããªã·ã¹ãã ã§ãããžã§ã¯ãããã§ãã¯ããã¢ãã©ã€ã¶ãŒã«æ
£ããããšãã§ããŸãã ããšãã°ãæè¿ãLinuxã«ãŒãã«ãå確èªããŸããããç°¡åã§ç°¡åã«ãªããŸããã
- ïŒ+ïŒJSONã³ã³ãã€ã«ããŒã¿ããŒã¹-è¿œå ã®ãã©ã°ã1ã€æå®ããããšã§ãCMakeãããžã§ã¯ãã®ãã®åœ¢åŒãååŸã§ããŸãã åæã«å¿
èŠãªãã¹ãŠã®æ
å ±ããããäžå¿
èŠãªããã»ã¹ã¯ãããŸããã ãµããŒããããŠããŸãã
- ïŒÂ±ïŒLD_PRELOAD-é¢æ°çœ®æã«ããã¢ãã©ã€ã¶ãŒã®çµ±åã ãããžã§ã¯ããæ¢ã«ãã®æ¹æ³ã§ã¢ã»ã³ãã«ãããŠããå Žåããã®ã¡ãœããã¯æ©èœããŸããã LD_PRELOADã䜿çšããŠéCMakeãããžã§ã¯ãã®JSONã³ã³ãã€ã«ããŒã¿ããŒã¹ãååŸã§ãããŠãŒãã£ãªãã£ïŒ Bearãªã© ïŒããããŸãã CMakeãšã¯å°ãéãããããŸããããµããŒããè¡ã£ãŠããŸãã ãŸãããããžã§ã¯ããèšå®ãããç°å¢å€æ°ã«äŸåããªãå Žåã¯ããããžã§ã¯ãã確èªããããšãã§ããŸãã ãããã£ãŠã±ã
å®æçãªãã¹ãã®ç»å Ž
ãœãããŠã§ã¢ããã¹ãããã«ã¯ããŸããŸãªæ¹æ³ããããŸãã ã¢ãã©ã€ã¶ãŒãšèšºæããã¹ãããããã®æãå¹æçãªå®è¡ã¯ããªãŒãã³ãããžã§ã¯ãã®å€§èŠæš¡ãªã³ãŒãããŒã¹ã§å®è¡ãããŸãã ãŸããçŽ30ã®äž»èŠãªãªãŒãã³ãœãŒã¹ãããžã§ã¯ããéžæããŸããã å
ã»ã©ãLinuxã§çµã¿ç«ãŠãããã¢ãã©ã€ã¶ãŒã1幎以äžååšããèšäºã®ãããžã§ã¯ããå®æçã«ãã§ãã¯ãããŠããããšãè¿°ã¹ãŸããã ãã¹ãŠãããŸãããããã«èŠããã ããããæ¬æ Œçãªãã¹ããéå§ããã ãã§ãã¢ãã©ã€ã¶ãŒã®æ¬ é¥ã®å
šäœåãããããŸããã åæãéå§ããåã«ãã³ãŒãã解æããŠå¿
èŠãªæ§æãèŠã€ããå¿
èŠããããŸãã åé¢äžå¯èœãªã³ãŒããåæã®å質ã«äžãã圱é¿ã¯ãããã§ãããç¶æ³ã¯äŸç¶ãšããŠäžå¿«ã§ãã ãã¹ãŠã®ã³ã³ãã€ã©ã«éæšæºã®æ¡åŒµæ©èœããããŸãããMS Visual C / C ++ã§é·ãéãµããŒãããŠãããGCCã§ã¯ã»ãšãã©æåãããã®æŠããéå§ããå¿
èŠããããŸããã ãªãã»ãšãã©ïŒ Windowsã§ã¯ãé·ãéGCCïŒMinGWïŒã§ã®äœæ¥ããµããŒãããŠããŸããããããã»ã©æ®åããŠããªããããç§ãã¡ããŠãŒã¶ãŒãåé¡ã¯ãããŸããã§ããã
ã³ã³ãã€ã©ãŒæ¡åŒµ
ãã®ã»ã¯ã·ã§ã³ã§ã¯ãGCCæ¡åŒµæ©èœã䜿çšããã³ãŒããã€ãŸãä»ã®ã©ãã«ãèŠãããªãã³ãŒãã«çŠç¹ãåœãŠãŸãã ãªãå¿
èŠãªã®ã§ããããïŒ ã»ãšãã©ã®ã¯ãã¹ãã©ãããã©ãŒã ãããžã§ã¯ãã§ã¯ã䜿çšãããå¯èœæ§ã¯äœãã§ãã ãŸããå®è·µã瀺ãããã«ããããã䜿çšãããŸãã Linuxã§ãããžã§ã¯ãããã¹ãããããã®ã·ã¹ãã ãéçºãããšãã«ããã®ãããªã³ãŒãã«åºäŒããŸããã ããããæšæºã©ã€ãã©ãªã®ã³ãŒãã解æãããšãã«äž»ãªåé¡ãçºçããŸããæ¡åŒµæ©èœãæ倧éã«æŽ»çšãããŠããŸãã ãããžã§ã¯ãã®ååŠçæžã¿ãã¡ã€ã«ã確èªããããšã¯ã§ããŸãããæé©åã®ããã«ã䜿ãæ
£ãã
memseté¢æ°ãã¹ããŒãã¡ã³ãåŒã§æ§æããããã¯ãã«ãªãããšããããŸãã ãããããŸãæåã«ã Linuxãããžã§ã¯ãããã¹ããããšãã«ãã©ã®ãããªæ°ãããã¶ã€ã³ã«åºäŒããŸãããïŒ
èŠãããæåã®æ¡åŒµåã®1ã€ã¯
ã€ãã·ã£ã©ã€ã¶ã«
æå®ãããŸãã ã ãããã䜿çšããŠãé
åãä»»æã®é åºã§åæåã§ããŸãã ããã¯ã
enumã§ã€ã³ããã¯ã¹ä»ããããŠããå Žåã«ç¹ã«äŸ¿å©ã§ããã€ã³ããã¯ã¹ãæ瀺çã«æå®ããããšã§ãèªã¿ãããããå°æ¥å€æŽããéã®ééãã®å¯èœæ§ãæžãããŸãã ããã¯ãšãŠãçŽ æµã§ã·ã³ãã«ã«èŠããŸãïŒ
enum Enum { A, B, C }; int array[] = { [A] = 10, [B] = 20, [C] = 30, }
ã¹ããŒãã®èå³ã®ããã«ããã®äŸãå°ãè€éã«ããŸãã
enum Enum { A, B, C }; struct Struct { int d[3]; }; struct Struct array2[50][50] = { [A][42].d[2] = 4 };
ã€ãŸãããã®æ§é ã§ã¯ãã€ã³ããã¯ã¹ä»ããšæ§é äœã®ã¡ã³ããŒã®åŒã³åºãã®ã·ãŒã±ã³ã¹ãåæååãšããŠäœ¿çšã§ããŸãã ç¯å²ã¯ã€ã³ããã¯ã¹ãšããŠæå®ããããšãã§ããŸãïŒ
int array[] = { [0 ... 99] = 0, [100 ... 199] = 10, }
å°ãããªãããã»ãã¥ãªãã£ã®èŠ³ç¹ããéåžžã«äŸ¿å©ãªGCCã®æ¡åŒµæ©èœã¯ãnullãã€ã³ã¿ãŒã«é¢é£ä»ããããŠããŸãã
NULLã®äœ¿çšã®åé¡ã«ã€ããŠã¯ããã§ã«å€ãã®èšèã
èšãããŠã
ãŸãã ãç¹°ãè¿ãã¯ããŸããã GCCã®å ŽåãC ++ã®
NULLã¯
__nullãšããŠå®£èšããããããç¶æ³ã¯ãããã«æ¹åãã
ãŸã ã ãããã£ãŠãGCCã¯èã®ãã®ãããªã·ã§ããããç§ãã¡ãä¿è·ããŸãã
int foo(int *a); int foo(int a); void test() { int a = foo(NULL); }
ã³ã³ãã€ã«ãããšããšã©ãŒãçºçããŸãã
test.c: In function 'void test()': test.c:20:21: error: call of overloaded 'foo(NULL)' is ambiguous int a = foo(NULL); ^ test.c:10:5: note: candidate: int foo(int*) int foo(int *a) { ^ test.c:14:5: note: candidate: int foo(int) int foo(int a) {
GCCã«ã¯ã__ attribute __ïŒïŒïŒïŒå±æ§ãèšå®ããæ©èœããããŸãã ãªã³ã¯ãã¢ã©ã€ã¡ã³ããæé©åããã®ä»å€ãã®ããšãå¶åŸ¡ã§ããé¢æ°ãå€æ°ãããã³åã®å±æ§ã®ãªã¹ãããããŸãã èå³æ·±ãå±æ§ã®1ã€ã¯
transparent_unionã§ãã ãã®ãããª
ãŠããªã³ãé¢æ°ãã©ã¡ãŒã¿ãŒã«ãããšãåŒæ°ãšããŠ
ãŠããªã³èªäœã ãã§ãªãããã®åæããã®ãã€ã³ã¿ãŒãæž¡ãããšãã§ããŸãã ãã®ã³ãŒãã¯æ£ããã§ãããïŒ
typedef union { long *d; char *ch; int *i; } Union __attribute((transparent_union)); void foo(Union arg); void test() { long d; char ch; int i; foo(&d);
transparent_unionã䜿çšããäŸã¯ã
åŸ
æ©é¢æ°ã§ã
ãint*ãŸãã¯
union wait *ãåãå
¥ããããšãã§ããŸãã ããã¯ãPOSIXããã³4.1BSDãšã®äºææ§ã®ããã«è¡ãããŸãã
ããããGCCã®ãã¹ããããé¢æ°ã«ã€ããŠèããããšãããã§ãããã é¢æ°ã®åã«å®£èšãããå€æ°ã䜿çšã§ããŸãã ãã¹ããããé¢æ°ããã€ã³ã¿ãŒã§æž¡ãããšãã§ããŸãïŒãã ããæãããªçç±ã«ãããã¡ã€ã³é¢æ°ã®çµäºåŸã«ãã®ãã€ã³ã¿ãŒã§åŒã³åºãããšã¯ã§ããŸããïŒã
int foo(int k, int b, int x1, int x2) { int bar(int x) { return k * x + b; } return bar(x2) - bar(x1); } void test() { printf("%d\n", foo(3, 4, 1, 10));
ãããããã®ãããªé¢æ°ããgotoãã芪é¢æ°ãã«ã§ããããšãç¥ã£ãŠããŸãããïŒ ããã¯ããã®ãããªé¢æ°ãå¥ã®é¢æ°ã«è»¢éããããšãšçµã¿åãããŠç¹ã«å°è±¡çã«èŠããŸãã
int sum(int (*f)(int), int from, int to) { int s = 0; for (int i = from; i <= to; ++i) { s += f(i); } return s; } int foo(int k, int b, int x1, int x2) { __label__ fail; int bar(int x) { if (x >= 10) goto fail; return k * x + b; } return sum(bar, x1, x2); fail: printf("Exceptions in my C?!\n"); return 42; } void test() { printf("%d\n", foo(3, 4, 1, 10));
å®éã«ã¯ããã®ãããªã³ãŒãã¯éåžžã«æ²ããçµæãããããå¯èœæ§ããããšããäºå®ã§ãïŒäŸå€ã®å®å
šæ§ã¯ãCãèšããŸã§ããªããRAIIã䜿çšããC ++ã§ãããªãè€éãªãããã¯ã§ãããããã£ãŠãããããªãæ¹ãè¯ãã§ãã
åŸè€ãšèšãã°ã GCCã§ã¯ãã¿ã°ãä¿åããŠããã®åŸã«ãã€ã³ã¿ãŒã眮ãããšãã§ããŸãã ãããŠãé
åã«æžã蟌ããšãå€æããŒãã«ãåŸãããŸãïŒ
int foo(); int test() { __label__ fail1, fail2, fail3; static void *errors[] = {&&fail1, &&fail2, &&fail3}; int rc = foo(); assert(rc >= 0 && rc < 3); if (rc != 0) goto *errors[rc]; return 0; fail1: printf("Fail 1"); return 1; fail2: printf("Fail 2"); return 2; fail3: printf("Fail 3"); return 3; }
ãããŠãããã¯Clangã®å°ããªæ¡åŒµã§ãã PVS-Studioã¯é·ãéãã®ã³ã³ãã€ã©ã䜿çšããããšãã§ããŸããããä»ã§ãèšèªãšã³ã³ãã€ã©ã«ç»å Žããæ°ãããã¶ã€ã³ã«é©ãããšã¯ãããŸããã ãããã®1ã€ã次ã«ç€ºããŸãã
void foo(int arr[static 10]); void test() { int a[9]; foo(a);
ãã®ã¬ã³ãŒãã䜿çšããŠãã³ã³ãã€ã©ã¯æž¡ãããé
åã«10å以äžã®èŠçŽ ãããããšã確èªãããªãå Žåã¯èŠåãåºããŸãã
test.c:16:5: warning: array argument is too small; contains 9 elements, callee requires at least 10 [-Warray-bounds] foo(a); ^ ~ test.c:8:14: note: callee declares array parameter as static here void foo(int arr[static 10]) ^ ~~~~~~~~~~~
ããŒã¿çã®ãã¹ããçµäºããŸããã ãŠã§ãŒã1
ã¢ãã©ã€ã¶ãŒã®å®å®ããããŒãžã§ã³ãããã¥ã¡ã³ããããã³çµ±åããã«ãããžã§ã¯ããæ€èšŒããããã®ããã€ãã®æ¹æ³ãæºåããåŸãã¯ããŒãºããã¹ããéå§ããŸããã
æåã®ãã¹ã¿ãŒã«ââã¢ãã©ã€ã¶ãŒãçºè¡ãå§ãããšããã¢ãã©ã€ã¶ãŒã«å®è¡å¯èœãã¡ã€ã«ãæäŸããã ãã§ã¯äžååã§ããããšãããããŸããã ããã°ããã補åããããå€ãã®ãšã©ãŒãèŠã€ãããŸããããããç§ã¯ããªãã®ã¢ããªã±ãŒã·ã§ã³ãä¿¡çšããŠããªãã®ã§ã/ usr / binã«ã€ã³ã¹ããŒã«ããŸããïŒããšããã¬ãã¥ãŒãåããŸããã æ®å¿µãªãããåŸè
ã®æ¹ãå€ãã£ãã ãããã£ãŠãå®è¡å¯èœãã¡ã€ã«ã§ã®ç¬ç«ããäœæ¥ã®å¯èœæ§ã«é¢ãããã©ãŒã©ã ãŠãŒã¶ãŒã®è°è«ã¯èªåŒµãããŸããã ãã®åœ¢åŒã§ã¯ããã¹ãŠã®äººãã¢ãã©ã€ã¶ãŒã䜿çšã§ããããŸãã¯äœ¿çšããããªããšã¯éããŸããã Linuxã§ãœãããŠã§ã¢ãé
åžããã«ã¯ãããã€ãã®äžè¬çãªæ¹æ³ã䜿çšããå¿
èŠããããŸãã
ããŒã¿çã®ãã¹ããçµäºããŸããã ãŠã§ãŒã2
æåã®ã¬ãã¥ãŒãåãåã£ãåŸããã¹ããåæ¢ããã»ãŒ2é±éã«ããã£ãŠããŒãã¯ãŒã¯ã«æ²¡é ããŸããã ä»ã®äººã®ã³ãŒãããã¹ããããšãã³ã³ãã€ã©ã«é¢ããããã«å€ãã®åé¡ãæããã«ãªããŸããã ãªããªã GCCã«åºã¥ããŠãããŸããŸãªãã©ãããã©ãŒã çšã®ã³ã³ãã€ã©ãšã¯ãã¹ã³ã³ãã€ã©ãäœæããããã®åŸãåœç€Ÿã®ã¢ãã©ã€ã¶ãŒã䜿çšããŠãããŸããŸãªéçã®ãœãããŠã§ã¢ããããã¹ããå§ããŸããã ååãšããŠãã¢ãã©ã€ã¶ãŒã¯ãã®ä»»åãåŠçããæè¬ã®ãã£ãŒãããã¯ãåãåããŸããããã¢ãã©ã€ã¶ãŒã¯ããµããŒãããå¿
èŠãããæ¡åŒµæ©èœã®ããã«ã³ãŒãã®äžéšãã¹ãããããŸããã
誀æ€ç¥ã¯éçã¢ãã©ã€ã¶ãŒã«åºæã®ãã®ã§ãããLinuxã§ã¯ãã®æ°ããããã«å¢ããŠããŸãã ãã®ãããæ°ãããã©ãããã©ãŒã ãšã³ã³ãã€ã©ã®èšºæã«åãçµã¿å§ããŸããã
倧ããªæ¹è¯ç¹ã¯ãDeb / Rpmããã±ãŒãžã®äœæã§ããã ç»å ŽåŸãPVS-Studioã®ã€ã³ã¹ããŒã«ã«å¯Ÿããäžæºã¯ãªããªããŸããã ãããããsudoã䜿çšããŠããã±ãŒãžãã€ã³ã¹ããŒã«ããããšã«æ¿æãã人ã¯1人ã ãã ã£ãã§ãããã ãã®æ¹æ³ã§ã»ãšãã©ãã¹ãŠã®ãœãããŠã§ã¢ãã€ã³ã¹ããŒã«ãããŸããã
ããŒã¿çã®ãã¹ããçµäºããŸããã ãŠã§ãŒã3
ãŸããæ¹èšã®ããã«çãäŒæ©ãåãã次ã®å€æŽãè¡ããŸããã
- è¿
éãªæ€èšŒã®ããã®æ§æãã¡ã€ã«ã®æåŠ-Deb / Rpmããã±ãŒãžã®å°å
¥åŸãæåã®å Žæã¯ã¢ãã©ã€ã¶ãŒã®æ§æãã¡ã€ã«ã«èšå
¥ããåé¡ã§å ããããŠããŸããã ã©ã€ã»ã³ã¹ãã¡ã€ã«ãžã®ãã¹ãšã¢ãã©ã€ã¶ãŒã¬ããŒããžã®ãã¹ã®2ã€ã®å¿
é ãã©ã¡ãŒã¿ãŒã®ã¿ã䜿çšããŠãæ§æãã¡ã€ã«ãªãã§ãããžã§ã¯ããè¿
éã«æ€èšŒããããã«ã¢ãŒããå€æŽããå¿
èŠããããŸããã ãã®ã¢ãŒãã®è©³çŽ°èšå®ã®å¯èœæ§ã¯æ®ããŸãã
- straceãŠãŒãã£ãªãã£ã®ãã°ã®åŠçãæ¹åãããŸãããæåã¯ã straceãŠãŒãã£ãªãã£ã®ãã°ã¯ããããã¿ã€ããäœæãããPerlèšèªã®ã¹ã¯ãªããã«ãã£ãŠåŠçãããŠããŸããã ã¹ã¯ãªããã¯ãã£ãããšåäœããåæã®äžŠååãäžååã§ããã ãã®æ©èœãC ++ã§æžãçŽããåŸããã¡ã€ã«åŠçã¯å éãã1ã€ã®ããã°ã©ãã³ã°èšèªã§ãã¹ãŠã®ã³ãŒãããµããŒãããããšã容æã«ãªããŸããã
- Deb / Rpmããã±ãŒãžã®å®æ-as ã¯ã€ãã¯ãã§ãã¯ã¢ãŒããæ©èœããã«ã¯ã straceãŠãŒãã£ãªãã£ãå¿
èŠã§ãæåã®ããã±ãŒãžã«Perl / Pythonã¹ã¯ãªãããå«ãŸããŠããããããã¹ãŠã®äŸåé¢ä¿ãããã«æ£ããç»é²ããããåŸã§ã¹ã¯ãªãããå®å
šã«ç Žæ£ãããŸããã åŸã«ãã°ã©ãã£ã«ã«ãããŒãžã£ãŒã䜿çšããŠã¢ãã©ã€ã¶ãŒãã€ã³ã¹ããŒã«ããéã®èŠåã«ã€ããŠäœäººãã®äººã
ãæžããã®ã§ãããã«ããããåé€ããŸããã ããã§ãç§ãã¡ãèªåçšã«èšå®ãããã¹ãæ¹æ³ã®å©ç¹ã«æ³šç®ããããšæããŸããæ°åã®Linuxãã£ã¹ããªãã¥ãŒã·ã§ã³ãDockerã«ãããã€ãããã€ã³ã¹ããŒã«ãããããã±ãŒãžãã€ã³ã¹ããŒã«ãããŸãã ã€ã³ã¹ããŒã«ãããããã°ã©ã ãå®è¡ããæ©èœããã¹ããããŸããã ãã®ãããªãã¹ãã«ãããããã±ãŒãžã«æ°ããå€æŽããã°ããå ããŠãã¹ãããããšãã§ããŸããã
- ã¢ãã©ã€ã¶ãŒãšããã¥ã¡ã³ãã®ãã®ä»ã®æ¹åã ãã¹ãŠã®ææãããã¥ã¡ã³ãã«åæ ããŸããã ããŠãã¢ãã©ã€ã¶ãŒã®ãã¡ã€ãã©ã€ãºã«é¢ããäœæ¥ã¯æ¢ãŸããŸããããããã¯æ°ãã蚺æãšæ¢åã®èšºæã®æ¹åã§ãã
ããŒã¿çã®ãã¹ããçµäºããŸããã ãŠã§ãŒã4ïŒãªãªãŒã¹åè£ïŒ
ã¢ãã©ã€ã¶ãŒé
åžã®æåŸã®æ³¢ã§ã¯ããŠãŒã¶ãŒã¯ã¢ãã©ã€ã¶ãŒã®ã€ã³ã¹ããŒã«ãéå§ãããã³æ§æã«åé¡ããªããªããŸããã ããããããã£ãŒãããã¯ãèŠã€ãã£ãå®éã®ãšã©ãŒã®äŸã誀æ€ç¥ã®äŸããããŸãã
ãŸãããŠãŒã¶ãŒã¯ã¢ãã©ã€ã¶ãŒã®é«åºŠãªèšå®ã«é¢å¿ãæã€ããã«ãªããŸããã ãã®ãããã¢ãã©ã€ã¶ãŒãMakefile / CMake / QMake / QtCreator / CLionã«çµ±åããæ¹æ³ã«ã€ããŠã®ããã¥ã¡ã³ãã®æ¹åãéå§ããŸããã ãããã©ã®ããã«èŠããããç§ã¯ããã«ç€ºããŸãã
ååã«éçºãããçµ±åæ¹æ³
Makefile / Makefile.amã§ã®çµ±å
çµ±åããã«ãããžã§ã¯ãããã§ãã¯ãã䟿å©ãã«ãããããããã¢ã»ã³ããªã·ã¹ãã ã«çŽæ¥çµ±åããããšã«ã¯ããã€ãã®å©ç¹ããããŸãã
- ã¢ãã©ã€ã¶ãŒã®åŸ®èª¿æŽã
- å¢ååæ;
- ã¢ã»ã³ããªã·ã¹ãã ã¬ãã«ã§ã®åæã®äžŠååã
- çµç«ã·ã¹ãã ã®ãã®ä»ã®å©ç¹ã
ã¢ãã©ã€ã¶ãŒãã³ã³ãã€ã©ãŒãšåãå Žæã§åŒã³åºããããšãç°å¢ãäœæ¥ãã£ã¬ã¯ããªãŒãããã³ãã¹ãŠã®ãã©ã¡ãŒã¿ãŒãã¢ãã©ã€ã¶ãŒçšã«æ£ããæ§æãããŸãã ãã®å Žåããã¹ãŠã®æ¡ä»¶ãæºããããæ£ããå®æ§åæãè¡ãããŸãã
Makefileã§ã®çµ±åã¯æ¬¡ã®ããã«ãªããŸãã
.cpp.o: $(CXX) $(CFLAGS) $(DFLAGS) $(INCLUDES) $< -o $@ pvs-studio --cfg $(CFG_PATH) --source-file $< --language C++ --cl-params $(CFLAGS) $(DFLAGS) $(INCLUDES) $<
CMake / CLionã®çµ±å
CMakeã§ã®ã¢ãã©ã€ã¶ãŒã®çµ±åãæ€èšããçµæãCLionã§PVS-Studioã䜿çšã§ããããã«ãªããŸããã ã¢ãã©ã€ã¶ãŒã¬ããŒãã®ãã¡ã€ã«ãåä¿¡ããããIDEã§èŠåã衚瀺ããŠåé¡ã®ããé åã衚瀺ã§ããŸãã
CMake / QtCreatorã§ã®çµ±å
QtCreatorã§CMakeãããžã§ã¯ããæäœããã«ã¯ãã¬ããŒããä¿åããããIDEã§ã¢ã©ãŒããããã«è¡šç€ºããããšãã§ããŸãã CLineãšã¯ç°ãªããQtCreatorã¯TaskList圢åŒã§ä¿åãããã¬ããŒãã衚瀺ããããã«éãããšãã§ããŸãã
QMake / QtCreatorã§ã®çµ±å
QMakeãããžã§ã¯ãã§ã¯ãç°¡åãªçµ±åæ¹æ³ãæäŸããŸããã
pvs_studio.target = pvs pvs_studio.output = true pvs_studio.license = /path/to/PVS-Studio.lic pvs_studio.cxxflags = -std=c++14 pvs_studio.sources = $${SOURCES} include(PVS-Studio.pri)
ãããã«
éçºäžã«äœã«å°éããŸãããïŒ
- ã¢ãã©ã€ã¶ãŒã¯ãããã±ãŒãžãŸãã¯ãªããžããªããç°¡åã«ã€ã³ã¹ããŒã«ã§ããŸãã
- ã¢ãã©ã€ã¶ãŒãã¢ã»ã³ããªã·ã¹ãã ã«çµ±åããã«ãã¹ããå®è¡ããããšã«ãããã¢ãã©ã€ã¶ãŒãç°¡åã«ç解ã§ããŸãã
- ã¢ãã©ã€ã¶ãŒãå®æçã«äœ¿çšããããã«ãåéçºè
ã®ãã·ã³ã§å¢ååæãæ§æã§ããŸãã
- ãã«ããµãŒããŒã§ãã«ã¹ãã£ã³ãèšå®ããŸãã
- äžè¬çãªIDEãšã®çµ±åã
ãã®ãããªæ¥œåšã¯ãã§ã«äººã
ã«èŠããããšãã§ããŸãã
ãã¡ãããã¢ãã©ã€ã¶ãŒãããŠã³ããŒãããŠè©Šãããšãã§ããŸãã ç§ãã¡ã®ãã¥ãŒã¹ããã©ããŒããæ€èšŒã®ããã«ãããžã§ã¯ããéä¿¡ããŸããããä»ã¯Linuxã§ïŒ
ãã®èšäºãè±èªåã®èŽè¡ãšå
±æãããå Žåã¯ã翻蚳ãªã³ã¯Svyatoslav RazmyslovïŒ
The Development History of PVS-Studio for Linuxã䜿çšããŠãã ããã