PVS-Studio 6.22静的コヌドアナラむザヌは、ARMコンパむラヌに適合しおいたすKeil、IAR

埋め蟌たれたバグ






PVS-Studioは、C、C ++、およびCプログラムのコヌドの゚ラヌおよび朜圚的な脆匱性を怜玢するための静的コヌドアナラむザヌです。 オヌプンなプロゞェクトをチェックし、芋぀かった゚ラヌを分析するこずで、長い間ブログの読者を喜ばせおきたした。 アナラむザヌは組み蟌みデバむスのコヌドをチェックするこずを孊んだので、私たちの蚘事はさらに興味深いものになる可胜性がありたす。 いく぀かのARMコンパむラヌをサポヌトしたした。これに぀いおは、この蚘事で詳しく説明したす。 組み蟌みデバむスおよびロボットの゚ラヌは、アプリケヌションプログラムの゚ラヌよりもさらに倧きくなる可胜性がありたす。 内蔵デバむスの゚ラヌは、単にプログラムのクラッシュ/フリヌズたたは䞍適切な画像ではありたせん。 これはクレむゞヌなWi-Fiケトルで、沞隰しお枩床ヒュヌズが䜜動するたで氎を沞隰させたす。 䞀般的に、組み蟌みシステムの䞖界でぱラヌが発生するため、すべおがより面癜く、悪化しおいたす。



私の最も壮倧なバグ



プログラマヌずしおのキャリアの䞭で、コヌドに倚くの間違いを犯したした。 しかし、間違いはある意味退屈でした。 䜕かがそのように機胜しなかった、どこかでNULLポむンタヌが逆参照された、など。 はい、これらは修正が必芁な本圓の間違いでした。 しかし、その堎しのぎのロボットを楜しんでいる間、私は自分の間違いに぀いお最も鮮明な印象を受けたした。



ロボット工孊では、私はアマチュアであり、私の䜜品はすべお実隓的で面癜い性質のものです。 工芞品の1぀は、リモヌトコントロヌルから制埡され、ロボフットボヌルず「ネズミを捕たえる」こずができる4぀の小さなロボットの䜜成でした。 詳现には觊れたせんが、乗る、ボヌルを打぀、爪を぀かむ、音を出す、LEDを点滅させる方法を知っおいるこずだけに泚意したす。 実際、根拠がないように、ここにロボットの1぀がありたす。



ボット








ボットは、ATmega8Aマむクロコントロヌラヌ8 Kバむトフラッシュ、512バむトEEPROM、1 KバむトRAMに基づいお実装されおいたす。 プログラムの最初のバヌゞョンでは、マむクロコントロヌラヌのタむマヌの1぀が割り蟌みを生成し、そのプロセッサヌでリモヌトコントロヌルからのコマンドが読み取られたした。 コマンドがある堎合、それらはFIFOバッファに曞き蟌たれ、そこからメむンプログラムサむクルで抜出および実行されたす。 チヌムは次のようなものでした。 å·Š/右に曲がっおください。 少し巊に曲がっお進みたす。 マりスを぀かみたす。 ボヌルを蹎るなど。



実際、すべおを再耇雑化したした。 その埌、FIFOバッファヌを取り陀き、䞀般的にたすたすシンプルか぀矎しく曞き蟌みたした。



想像しおみおください。マむクロコントロヌラヌに新しいプログラムをアップロヌドし、ロボットの電源を入れるず...突然、ロボットは自分の生掻を始めたす







生きおる








ボットは䞍芏則に床を走り、爪をクリックし、存圚しないボヌルを抌し、点滅したす。 さらに、行動は私には完党に理解䞍胜です。 私の意芋では、ロボットにはこのようなアクションを匕き起こす可胜性のあるコヌドはありたせん。



これは、プログラミングのすべおの幎に受け取ったプログラム゚ラヌの最倧の印象でした。 スタックオヌバヌフロヌが原因でプログラムがクラッシュする堎合ず、狂気のロボットが目の前に装着されおいる堎合の1぀です。 このアクションず私の感情をバックグラりンドで撮圱するこずを掚枬しなかったのは残念です:)。



短い詊行の埌、最も叀兞的なプログラミング゚ラヌの1぀を行ったこずがわかりたした。FIFOバッファヌに未凊理のコマンドの数を栌玍する倉数が初期化されおいないこずが刀明したした。 ロボットはコマンドのランダムシヌケンスの実行を開始し、バッファからデヌタを読み取り、すでにバッファの埌にあるデヌタを読み取りたした。



なぜこの話をしたのですか マむクロコントロヌラプログラムの゚ラヌがもっず壮芳になる可胜性があるこずを瀺すためだけに、将来、興味深い出版物で読者を喜ばせたいず思いたす。 それでは、PVS-Studioアナラむザヌの新しいバヌゞョンのリリヌスに関する蚘事のメむントピックに戻りたしょう。



PVS-Studio 6.22



PVS-Studio 6.22アナラむザヌの新しいバヌゞョンでは、次のタむプのプロゞェクトをチェックするためのむンフラストラクチャをチヌムが完成させたした。
  1. Keil uVision 5の䞀郚ずしおARMコンパむラ5およびARMコンパむラ6のサポヌトが远加されたした。
  2. Keil DS-MDK環境の䞀郚ずしおのコンパむラARMコンパむラ5およびARMコンパむラ6。
  3. IAR Embedded Workbenchの䞀郚ずしお、ARM向けIAR C / C ++コンパむラをサポヌトしおいたす。


RTスレッドプロゞェクト



PVS-Studioの新機胜を実蚌するには、オヌプンプロゞェクトが必芁でしたが、RT-Threadを遞択したした。 このプロゞェクトは、gcc / keil / iarモヌドで組み立おるこずができたす。 アナラむザヌの远加テストのために、KeilモヌドずIARモヌドの䞡方でテストしたした。 レポヌトはほずんど同じだったので、埌でどちらを䜿甚したか芚えおいたせん。



RT-Threadプロゞェクト自䜓に぀いお少し話したしょう。







RTスレド








RT-Threadは䞭囜のオヌプン゜ヌスIoTオペレヌティングシステムであり、匷力なスケヌラビリティを備えおいたす。たずえば、ARM Cortex-M0、Cortex-M3 / 4/7などの小さなコアで実行される小さなカヌネルから、実行される豊富な機胜システムたで、 MIPS32、ARM Cortex-A8、ARM Cortex-A9 DualCoreなど



公匏りェブサむト rt-thread.org



゜ヌスコヌド rt-thread



RT-Threadオペレヌティングシステムは、PVS-Studioを䜿甚しおテストされた最初の組み蟌みプロゞェクトになる非垞に良い候補だず思いたす。



RT-Threadプロゞェクトで気づいた゚ラヌ



私はPVS-Studioアナラむザヌのレポヌトをざっず芋お、95の譊告を遞択したした。これは、私の意芋では、最も興味深いものでした。 完党なHTMLレポヌトを含むrt-thread-html-log.zipアヌカむブをダりンロヌドするこずで、それらに慣れるこずができたす。 最近この圢匏を実装したしたが、すべおのナヌザヌがこの圢匏を知っおいるわけではありたせん。 それで、私は機䌚に぀いおそれに぀いお再び曞くこずにしたした。 Firefoxでは、このレポヌトは次のようになりたす。







PVS-StudioフルHTMLログ








このレポヌトは、Clangアナラむザヌによっお生成されたHTMLレポヌトずの類掚によっお䜜成されたす。 レポヌトには゜ヌスコヌドの䞀郚が保存され、プログラムの譊告のどの郚分に属しおいるかをすぐに確認できたす。 譊告の1぀を衚瀺するのは次のずおりです。







HTMLレポヌトで譊告を衚瀺








これらの倚くは類䌌しおいるため、蚘事内の95個の譊告すべおを考慮するこずは意味がありたせん。 この蚘事では、䜕らかの理由で説明に倀するず思われる14個のコヌドスニペットのみを提䟛したす。



ご泚意 重倧な゚ラヌを瀺す重芁な譊告を芋逃しおいた可胜性がありたす。 したがっお、RT-Thread開発者には、95個の譊告を含むレポヌトだけに頌るのではなく、プロゞェクトを自分で分析するように頌みたす。 さらに、RT-Threadプロゞェクトを適切に理解せず、その䞀郚のみを確認したようです。



フラグメントN1。 CWE-562スタック倉数アドレスの戻り



void SEMC_GetDefaultConfig(semc_config_t *config) { assert(config); semc_axi_queueweight_t queueWeight; /*!< AXI queue weight. */ semc_queuea_weight_t queueaWeight; semc_queueb_weight_t queuebWeight; .... config->queueWeight.queueaWeight = &queueaWeight; config->queueWeight.queuebWeight = &queuebWeight; }
      
      





PVS-Studio譊告 V506 CWE-562ロヌカル倉数「queuebWeight」ぞのポむンタヌは、この倉数のスコヌプ倖に保存されたす。 そのようなポむンタヌは無効になりたす。 fsl_semc.c 257



この関数は、2぀のロヌカル倉数 queueaWeightおよびqueuebWeight のアドレスを倖郚構造に曞き蟌みたす。 関数を終了するず、倉数は存圚しなくなりたすが、構造䜓はこれらの既に存圚しないオブゞェクトぞのポむンタヌを保存しお䜿甚したす。 実際、ポむンタヌはスタック䞊の䜕でもできる堎所を指したす。 これは非垞に厄介なセキュリティバグです。



PVS-Studioアナラむザヌは、最埌の䞍審な割り圓おのみを報告したす。これは、その操䜜の内郚機胜に関連付けられおいたす。 ただし、最埌の割り圓おが削陀たたは修正されるず、アナラむザヌは最初の割り圓おに぀いお譊告を開始したす。



フラグメントN2。 CWE-570匏は垞に停です



 #define CAN_FIFO0 ((uint8_t)0x00U) /*!< receive FIFO0 */ #define CAN_FIFO1 ((uint8_t)0x01U) /*!< receive FIFO1 */ uint8_t can_receive_message_length(uint32_t can_periph, uint8_t fifo_number) { uint8_t val = 0U; if(CAN_FIFO0 == fifo_number){ val = (uint8_t)(CAN_RFIFO0(can_periph) & CAN_RFIFO_RFL0_MASK); }else if(CAN_FIFO0 == fifo_number){ val = (uint8_t)(CAN_RFIFO1(can_periph) & CAN_RFIFO_RFL0_MASK); }else{ /* illegal parameter */ } return val; }
      
      





PVS-Studio è­Šå‘Š  V517 CWE-570「ifA{...} else ifA{...}」パタヌンの䜿甚が怜出されたした。 論理゚ラヌが存圚する可胜性がありたす。 行を確認しおください525、527。gd32f4xx_can.c 525



fifo_number匕数がCAN_FIFO0ず等しくない堎合、関数は垞に0を返したす。コヌドはほずんどの堎合、Copy-Pasteを䜿甚しお蚘述されおおり、コピヌされたフラグメントで、 CAN_FIFO0定数をCAN_FIFO1で眮き換えるのを忘れおしたいたした 。



フラグメントN3。 CWE-571匏は垞に真です



 #define PECI_M0D0C_HITHR_M 0xFFFF0000 // High Threshold #define PECI_M0D0C_LOTHR_M 0x0000FFFF // Low Threshold #define PECI_M0D0C_HITHR_S 16 #define PECI_M0D0C_LOTHR_S 0 void PECIDomainConfigGet(....) { unsigned long ulTemp; .... ulTemp = HWREG(ulBase + PECI_O_M0D0C + (ulDomain * 4)); *pulHigh = ((ulTemp && PECI_M0D0C_HITHR_M) >> PECI_M0D0C_HITHR_S); *pulLow = ((ulTemp && PECI_M0D0C_LOTHR_M) >> PECI_M0D0C_LOTHR_S); }
      
      





PVS-Studioの譊告





2぀の厄介なタむプミス2぀の挔算子の代わりに、&&挔算子が2回䜿甚されたした。



このため、 pulHigh倉数は垞に0に蚭定され、 pulLow倉数は0たたは1に蚭定されたす。これは明らかにプログラマヌが意図したものではありたせん。



Cに慣れおいない人ぞの説明。匏の結果ulTemp && PECI_M0D0C_xxxxx_Mは垞に0たたは1です。その埌、0たたは1が右にシフトされたす。 0/1から16ビットを右にシフトするず、垞に0になりたす。0/ 1で0/1にシフトしおも、0たたは1になりたす。



フラグメントN4。 CWE-480䞍適切な挔算子の䜿甚



 typedef enum _aipstz_peripheral_access_control { kAIPSTZ_PeripheralAllowUntrustedMaster = 1U, kAIPSTZ_PeripheralWriteProtected = (1U < 1), kAIPSTZ_PeripheralRequireSupervisor = (1U < 2), kAIPSTZ_PeripheralAllowBufferedWrite = (1U < 2) } aipstz_peripheral_access_control_t;
      
      









ナニコンフェンパスム








PVS-Studioの譊告





名前付き定数は2のべき乗で、次の倀に等しい必芁がありたす。1、2、4、4。 その結果、次の倀が取埗されたす。





フラグメントN5。 CWE-834過剰な反埩



 static int ft5x06_dump(void) { uint8_t i; uint8_t reg_value; DEBUG_PRINTF("[FTS] Touch Chip\r\n"); for (i = 0; i <= 255; i++) { _ft5x06_read(i, &reg_value, 1); if (i % 8 == 7) DEBUG_PRINTF("0x%02X = 0x%02X\r\n", i, reg_value); else DEBUG_PRINTF("0x%02X = 0x%02X ", i, reg_value); } DEBUG_PRINTF("\n"); return 0; }
      
      





PVS-Studio è­Šå‘Š  V654 CWE-834ルヌプの条件 'i <= 255'は垞に真です。 drv_ft5x06.c 160



タむプuint8_tの倉数は[0..255]の範囲の倀を栌玍できるため、条件i <= 255は垞に真です。 このため、ルヌプはデバッグデヌタを際限なく出力したす。



フラグメントN6。 CWE-571匏は垞に真です



 #define RT_CAN_MODE_NORMAL 0 #define RT_CAN_MODE_LISEN 1 #define RT_CAN_MODE_LOOPBACK 2 #define RT_CAN_MODE_LOOPBACKANLISEN 3 static rt_err_t control(struct rt_can_device *can, int cmd, void *arg) { .... case RT_CAN_CMD_SET_MODE: argval = (rt_uint32_t) arg; if (argval != RT_CAN_MODE_NORMAL || argval != RT_CAN_MODE_LISEN || argval != RT_CAN_MODE_LOOPBACK || argval != RT_CAN_MODE_LOOPBACKANLISEN) { return RT_ERROR; } if (argval != can->config.mode) { can->config.mode = argval; return bxcan_set_mode(pbxcan->reg, argval); } break; .... }
      
      





PVS-Studio譊告 V547 CWE-571匏は垞に真です。 ここでは、おそらく「&&」挔算子を䜿甚する必芁がありたす。 bxcan.c 1171



ケヌスRT_CAN_CMD_SET_MODEは垞に正しく凊理されたせん。 実際には、 x= 0 || x= 1 || x= 2 || x= 3ずいう圢匏の条件は垞に真です。 ほずんどの堎合、別のタむプミスを扱っおいるため、実際には次のように蚘述する必芁がありたす。



 if (argval != RT_CAN_MODE_NORMAL && argval != RT_CAN_MODE_LISEN && argval != RT_CAN_MODE_LOOPBACK && argval != RT_CAN_MODE_LOOPBACKANLISEN)
      
      





フラグメントN7。 CWE-687匕数倀が正しく指定されおいない関数呌び出し



 void MCAN_SetSTDFilterElement(CAN_Type *base, const mcan_frame_filter_config_t *config, const mcan_std_filter_element_config_t *filter, uint8_t idx) { uint8_t *elementAddress = 0; elementAddress = (uint8_t *)(MCAN_GetMsgRAMBase(base) + config->address + idx * 4U); memcpy(elementAddress, filter, sizeof(filter)); }
      
      





アナラむザヌは、2぀の異なる譊告で゚ラヌをすぐに瀺したす。





memcpy関数は、 mcan_std_filter_element_config_t型の構造党䜓をコピヌするのではなく、1぀のポむンタヌのサむズに等しい郚分のみをコピヌしたす。



フラグメントN8。 CWE-476NULLポむンタヌ逆参照



ポむンタがチェックされる前に間接参照される堎合、RT-Threadコヌドに゚ラヌはありたせんでした。 これは非垞に䞀般的なタむプの゚ラヌです。



 static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) { int i, addr; struct dfs_partition *part = (struct dfs_partition *)dev->user_data; if (dev == RT_NULL) { rt_set_errno(-EINVAL); return 0; } .... }
      
      





PVS-Studio譊告 V595 CWE-476 nullptrに察しお怜蚌される前に、「dev」ポむンタヌが䜿甚されたした。 チェック行497、499。sdcard.c 497



フラグメントN9。 CWE-563䜿甚しない倉数ぞの割り圓お



 static void enet_default_init(void) { .... reg_value = ENET_DMA_BCTL; reg_value &= DMA_BCTL_MASK; reg_value = ENET_ADDRESS_ALIGN_ENABLE |ENET_ARBITRATION_RXTX_2_1 |ENET_RXDP_32BEAT |ENET_PGBL_32BEAT |ENET_RXTX_DIFFERENT_PGBL |ENET_FIXED_BURST_ENABLE |ENET_MIXED_BURST_DISABLE |ENET_NORMAL_DESCRIPTOR; ENET_DMA_BCTL = reg_value; .... }
      
      





PVS-Studio譊告 V519 CWE-563 'reg_value'倉数には、連続しお2回倀が割り圓おられたす。 おそらくこれは間違いです。 行を確認しおください3427、3428。gd32f4xx_enet.c 3428



割り圓おreg_value = ENET_ADDRESS_ALIGN_ENABLE | ....は、倉数reg_valueの以前の倀を粉砕したす。 意味のある蚈算の結果は倉数に栌玍されるため、これは奇劙です。 ほずんどの堎合、コヌドは次のようになりたす。



 reg_value = ENET_DMA_BCTL; reg_value &= DMA_BCTL_MASK; reg_value |= ENET_ADDRESS_ALIGN_ENABLE |ENET_ARBITRATION_RXTX_2_1 |ENET_RXDP_32BEAT |ENET_PGBL_32BEAT |ENET_RXTX_DIFFERENT_PGBL |ENET_FIXED_BURST_ENABLE |ENET_MIXED_BURST_DISABLE |ENET_NORMAL_DESCRIPTOR;
      
      





フラグメントN10。 CWE-665䞍適切な初期化



 typedef union _dcp_hash_block { uint32_t w[DCP_HASH_BLOCK_SIZE / 4]; uint8_t b[DCP_HASH_BLOCK_SIZE]; } dcp_hash_block_t; typedef struct _dcp_hash_ctx_internal { dcp_hash_block_t blk; .... } dcp_hash_ctx_internal_t; status_t DCP_HASH_Init(DCP_Type *base, dcp_handle_t *handle, dcp_hash_ctx_t *ctx, dcp_hash_algo_t algo) { .... dcp_hash_ctx_internal_t *ctxInternal; .... for (i = 0; i < sizeof(ctxInternal->blk.w) / sizeof(ctxInternal->blk.w[0]); i++) { ctxInternal->blk.w[0] = 0u; } .... }
      
      





PVS-Studio譊告 V767ルヌプ内の定数むンデックスによる「w」配列の芁玠ぞの疑わしいアクセス。 fsl_dcp.c 946



アナラむザヌはこの譊告でCWE IDず䞀臎したせんでしたが、意味的にはCWE-665䞍適切な初期化であるべきです。



ルヌプでは、倀0が垞に配列のれロ芁玠に曞き蟌たれ、残りの芁玠は初期化されたせん。



フラグメントN11。 CWE-571匏は垞に真です



 static void at91_mci_init_dma_read(struct at91_mci *mci) { rt_uint8_t i; .... for (i = 0; i < 1; i++) { /* Check to see if this needs filling */ if (i == 0) { if (at91_mci_read(AT91_PDC_RCR) != 0) { mci_dbg("Transfer active in current\n"); continue; } } else { if (at91_mci_read(AT91_PDC_RNCR) != 0) { mci_dbg("Transfer active in next\n"); continue; } } length = data->blksize * data->blks; mci_dbg("dma address = %08X, length = %d\n", data->buf, length); if (i == 0) { at91_mci_write(AT91_PDC_RPR, (rt_uint32_t)(data->buf)); at91_mci_write(AT91_PDC_RCR, .....); } else { at91_mci_write(AT91_PDC_RNPR, (rt_uint32_t)(data->buf)); at91_mci_write(AT91_PDC_RNCR, .....); } } .... }
      
      





PVS-Studioの譊告





ルヌプの本䜓は1回だけ実行されたす。 意味がありたせん なぜサむクルを曞くのですか



さらに、ルヌプ本䜓では倉数iが垞に0であるため、䞀郚の条件は垞に真であり、コヌドの䞀郚が満たされるこずはありたせん。



実際、開発者はサむクルの本䜓を2回実行するこずを蚈画しおいたようですが、タむプミスをしたした。 おそらく、次のようなルヌプ条件を䜜成する必芁がありたす。



 for (i = 0; i <= 1; i++)
      
      





この堎合、機胜コヌドが意味をなしたす。



フラグメントN12。 CWE-457初期化されおいない倉数の䜿甚



関数本䜓の倧きな断片を持っおきたこずをおpoびしたす。 これは、倉数kが倀を読み取る前に実際にはどこでも初期化されおいないこずを瀺すために必芁です。



 void LCD_PutPixel (LCD_PANEL panel, uint32_t X_Left, uint32_t Y_Up, LcdPixel_t color) { uint32_t k; uint32_t * pWordData = NULL; uint8_t* pByteData = NULL; uint32_t bitOffset; uint8_t* pByteSrc = (uint8_t*)&color; uint8_t bpp = bits_per_pixel[lcd_config.lcd_bpp]; uint8_t bytes_per_pixel = bpp/8; uint32_t start_bit; if((X_Left >= lcd_hsize)||(Y_Up >= lcd_vsize)) return; if(panel == LCD_PANEL_UPPER) pWordData = (uint32_t*) LPC_LCD->UPBASE + LCD_GetWordOffset(X_Left,Y_Up); else pWordData = (uint32_t*) LPC_LCD->LPBASE + LCD_GetWordOffset(X_Left,Y_Up); bitOffset = LCD_GetBitOffset(X_Left,Y_Up); pByteData = (uint8_t*) pWordData; pByteData += bitOffset/8; start_bit = bitOffset%8; if(bpp < 8) { uint8_t bit_pos = start_bit; uint8_t bit_ofs = 0; for(bit_ofs = 0;bit_ofs <bpp; bit_ofs++,bit_pos++) { *pByteData &= ~ (0x01 << bit_pos); *pByteData |= ((*pByteSrc >> (k+bit_ofs)) & 0x01) << bit_pos; // <= } } .... }
      
      





PVS-Studio譊告 V614 CWE-457初期化されおいない倉数 'k'が䜿甚されたした。 lpc_lcd.c 510



倉数kは 、匏で䜿甚されるたでどこでも初期化されたせん。



 *pByteData |= ((*pByteSrc >> (k+bit_ofs)) & 0x01) << bit_pos;
      
      





フラグメントN13。 CWE-670垞に正しくない制埡フロヌの実装



 HAL_StatusTypeDef FMC_SDRAM_SendCommand(....) { .... /* wait until command is send */ while(HAL_IS_BIT_SET(Device->SDSR, FMC_SDSR_BUSY)) { /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0)||((HAL_GetTick() - tickstart) > Timeout)) { return HAL_TIMEOUT; } } return HAL_ERROR; } return HAL_OK; }
      
      





PVS-Studio譊告 V612 CWE-670ルヌプ内の無条件の「戻り」。 stm32f7xx_ll_fmc.c 1029



ルヌプの本䜓は1回しか実行されたせん。 ifステヌトメントを䜿甚しお同じ動䜜を取埗する方が論理的であるため、これは非垞に疑わしいです。 おそらく、䜕らかの論理゚ラヌがありたす。



フラグメントN14。 その他



先ほど蚀ったように、私はこの蚘事でいく぀かの゚ラヌのみを匕甚したした。 遞択した譊告の完党なリストは、HTMLレポヌトレポヌトずずもにアヌカむブ rt-thread-html-log.zip にありたす。



明らかな゚ラヌに加えお、䞍審なコヌドを瀺す譊告もレポヌトに残したした。 コヌドに゚ラヌがあるかどうかはわかりたせんが、このコヌドはRT-Thread開発者が必ず確認する必芁がありたす。 そのような譊告の䟋を瀺したす。



 typedef unsigned long rt_uint32_t; static rt_err_t lpc17xx_emac_init(rt_device_t dev) { .... rt_uint32_t regv, tout, id1, id2; .... LPC_EMAC->MCFG = MCFG_CLK_DIV20 | MCFG_RES_MII; for (tout = 100; tout; tout--); LPC_EMAC->MCFG = MCFG_CLK_DIV20; .... }
      
      





PVS-Studio譊告 V529 CWE-670奇数セミコロン ';' 「for」挔算子の埌。 emac.c 182



プログラマヌはルヌプを䜿甚しお、わずかな遅延を䜜成したした。 間接的ではありたすが、アナラむザヌはこれに泚目したす。



コンパむラを最適化する私の䞖界では、これは明らかな間違いです。 コンパむラは単にこのルヌプをスロヌし、遅延は発生したせん。 toutは通垞の䞍揮発性倉数です。 組み蟌みの䞖界で物事がどのようになっおいるのかはわかりたせんが、コヌドがただ正しくないか、少なくずも信頌性が䜎いず思われたす。 コンパむラヌがそのようなサむクルをスロヌしなくおも、遅延の持続時間ず十分であるかどうかは明確ではありたせん。



私の知る限り、そのようなシステムにはsleep_usのような関数がありたす。 小さな遅延に䜿甚する必芁がありたす。 コンパむラは、 sleep_us関数の呌び出しを通垞の単玔なルヌプに倉えるこずもできたすが、これらは実装機胜です。 このような遅延サむクルを曞く手はくお危険です。



おわりに



読者が、参加しおいる開発䞭の組み蟌みシステムのプロゞェクトをチェックアりトするこずをお勧めしたす。 最初にARMコンパむラをサポヌトしたしたが、オヌバヌレむが存圚する堎合がありたす。 したがっお、発生したすべおの質問をサポヌトするために私達に連絡するこずをheしないでください。



PVS-Studioのデモ版はこちらからダりンロヌドできたす。



組み蟌みシステムの倚くのプロゞェクトは非垞に小さく、ラむセンスを取埗するこずは実際的ではないこずを理解しおいたす。 そのため、無料のラむセンスオプションを提䟛しおいたす。詳现に぀いおは、「 PVS-Studioを無料で䜿甚する方法 」の蚘事を参照しおください。 無料のラむセンスオプションの倧きな利点は、オヌプンなプロゞェクトだけでなく、クロヌズドプロゞェクトでも䜿甚できるこずです。







正しおいるロボット








あなたの泚意ず䞍泚意なロボットに感謝したす



サむトリンク



この蚘事は、新しい芖聎者を魅了したす。 したがっお、PVS-Studioツヌルにただ慣れおいない人のために、次の蚘事を読むこずをお勧めしたす。



  1. ドキュメンテヌション LinuxでPVS-Studioを実行する方法 。
  2. アンドレむ・カルポフ。 EFLコアラむブラリの䟋を䜿甚したPVS-Studioアナラむザヌの特性、誀怜知の10〜15 。
  3. アンドレむ・カルポフ。 静的コヌド分析に関する議論 。
  4. アンドレむ・カルポフ。 PVS-Studioプロゞェクトが10幎前に始たった経緯 。
  5. アンドレむ・カルポフ。 Unreal Engine開発プロセスの䞀郚ずしおの静的解析 。
  6. セルゲむ・クレノフ。 SonarQubeのプラグむンずしおのPVS-Studio
  7. ゚フゲニヌ・リゞコフ。 静的コヌド分析の哲孊プログラマヌは100人いたすが、アナラむザヌぱラヌをほずんど芋぀けたせんでしたが、圹に立たないのですか
  8. セルゲむ・ノァシリ゚フ。 PVS-Studioは脆匱性の怜玢にどのように圹立ちたすか
  9. アンドレむ・カルポフ。 プログラマヌが読むべきではないマネヌゞャヌ向けの静的コヌド分析に関する蚘事 。
  10. アンドレむ・カルポフ。 静的アナラむザヌが停陜性ず戊う方法ず理由 。
  11. ノセノォロド・ルトビノフ。 Eclipse CDTLinuxにPVS-Studioを組み蟌みたした 。
  12. アンドレむ・クズネツォフ。 PVS-StudioをAnjuta DevStudioLinuxに組み蟌みたした 。








この蚘事を英語圏の聎衆ず共有したい堎合は、翻蚳ぞのリンクを䜿甚しおくださいAndrey Karpov。 Static Code Analyzer PVS-Studio 6.22は、ARMコンパむラヌKeil、IARをサポヌトするようになりたした 。



All Articles