3 Replies Latest reply on Jul 11, 2014 12:19 PM by SeyhanA_31

    Memory leak when using wiced_wifi_scan_networks

      Hi,

       

      I can easily reproduce memory leak issue with the following sequence:

       

      1) Connect to Wifi AP with wiced_wifi_join & wicked_network_up to bring up the connection.

      2) delay for 1 second or 2... actually this is not necessary.

      3) disconnect the wifi connection by calling wiced_network_down

      4) call scan networks by calling wicked_wifi_scan_networks (NOTE: this will always timeout after a scan success)

      5) print system memory

      6) Go back to step 1.

       

      PS. by executing above step you will see system memory total allocated spec increases on each loop... the issue seems to be scan timeout after wiced_network_down. When scan failed with timeout the memory increases... By the way, scan timeout can only be reproduced after you call wiced_network_down.

       

      Here is the code if needed:

       

       

      void application_start( )

      {

        uint8_t FirstTimeConneced = 0;

          wiced_init( );

       

          while(1)

          {

        //Sleep for 1 seconds

              wiced_rtos_delay_milliseconds(1*SECONDS);

       

              if (!FirstTimeConneced)

              {

                  char SSIDToConnect[32] = "AP_2.4G"; //Change to connect your AP

                  char PassWord[32] = "8888888888"; //Change to connect your AP

                  wiced_result_t result = wiced_wifi_join( SSIDToConnect, WICED_SECURITY_WPA2_MIXED_PSK, (uint8_t*)PassWord, 10, NULL ); //Change the security type according to your AP

       

                  WPRINT_APP_INFO( ( "AP Connect Result = %d\r\n",  result) );

       

                  if (result == WICED_SUCCESS)

                  {

                  if (wiced_network_up( WICED_STA_INTERFACE, WICED_USE_EXTERNAL_DHCP_SERVER, NULL ) == WICED_SUCCESS)

                  {

                  FirstTimeConneced = 1;

                  }

                  }

              }

       

              if (wiced_network_is_up( WICED_STA_INTERFACE ) == WICED_TRUE)

              {

              wiced_network_down(WICED_STA_INTERFACE);

              WPRINT_APP_INFO( ( "NetworkConnection is DOWN\r\n") );

              FirstTimeConneced = 0;

              }

       

              print_System_memory();

       

              wiced_result_t scanApiResult = wiced_wifi_scan_networks(scan_result_handler, NULL );

       

              if (scanApiResult != WICED_SUCCESS)

              {

              WPRINT_APP_INFO( ( "wiced_wifi_scan_networks failed with error code = %d\r\n", scanApiResult) );

              }

       

          }

      }

       

       

      static void print_System_memory( void )

      {

          volatile struct mallinfo mi = mallinfo( );

       

          WPRINT_APP_INFO( ("\r\n-------------------SYS DBG MEM HEAP DIAGNOSTIC-----------------------\r\n") );

       

          WPRINT_APP_INFO( ("malloc_info {\r\n"

                            "\tarena:   \t%5d;\t/* total space allocated from system */\r\n"

                            "\tordblks: \t%5d;\t/* number of non-inuse chunks */\r\n"

                            "\tsmblks:  \t%5d;\t/* unused -- always zero */\r\n"

                            "\thblks:   \t%5d;\t/* number of mmapped regions */\r\n"

                            "\thblkhd:  \t%5d;\t/* total space in mmapped regions */\r\n"

                            "\tusmblks: \t%5d;\t/* unused -- always zero */\r\n"

                            "\tfsmblks: \t%5d;\t/* unused -- always zero */\r\n"

                            "\tuordblks:\t%5d;\t/* total allocated space */\r\n"

                            "\tfordblks:\t%5d;\t/* total non-inuse space */\r\n"

                            "\tkeepcost:\t%5d;\t/* top-most, releasable (via malloc_trim) space */\r\n"

                            "};\r\n",

                            mi.arena,

                            mi.ordblks,

                            mi.smblks,

                            mi.hblks,

                            mi.hblkhd,

                            mi.usmblks,

                            mi.fsmblks,

                            mi.uordblks,

                            mi.fordblks,

                            mi.keepcost ));

      }

       

       

      /*

      * Callback function to handle scan results

      */

      wiced_result_t scan_result_handler( wiced_scan_handler_result_t* malloced_scan_result )

      {

          malloc_transfer_to_curr_thread( malloced_scan_result );

       

          if (malloced_scan_result->scan_complete != WICED_TRUE)

          {

              wiced_scan_result_t* record = &malloced_scan_result->ap_details;

              record->SSID.val[record->SSID.len] = 0; /* Ensure the SSID is null terminated */

       

              WPRINT_APP_INFO( ( "%3d ", record_count ) );

              print_scan_result(record);

              ++record_count;

          }

          else

          {

              wiced_time_t scan_end_time;

              wiced_time_get_time(&scan_end_time);

              WPRINT_APP_INFO( ("\r\nScan complete in %lu milliseconds\r\n", scan_end_time - scan_start_time) );

          }

       

          free( malloced_scan_result );

       

          return WICED_SUCCESS;

      }

        • 1. Re: Memory leak when using wiced_wifi_scan_networks
          SeyhanA_31

          Hi,

           

          I have duplicated the problem and looking into it for fix.

           

          Thanks,

          Seyhan

          • 2. Re: Memory leak when using wiced_wifi_scan_networks

            Hi,

             

            I encountered the same problem, too.  Hence, I had to use platform_reboot() after each wiced_network_down.

            • 3. Re: Memory leak when using wiced_wifi_scan_networks
              SeyhanA_31

              Hi,

               

              After scanning the network, all scanned data allocated by the lower level interface needs to be freed by the application by provided handler. The wiced_wifi_scan_networks() call needs to complete before calling the wiced_wifi_join() again. It could be achieved by implementing a semaphore. Get the semaphore before calling wiced_wifi_join() and set the semaphore where there are no data returned to the scan network handler. The posted code is updated with callback_sema for example.

               

              Meanwhile, caller for the wiced_wifi_join() could wait for join to complete by supplying a semaphore to the wiced_wifi_join() call. Again the posted code is updated with connection_sema to show usage.


              -----------------------------------------------------------------------------

              static wiced_semaphore_t callback_sema;

              static wiced_semaphore_t connection_sema;

               

              void application_start( )

              {

               

                  uint8_t FirstTimeConneced = 0;

                  wiced_init();

               

                  wiced_rtos_init_semaphore(&callback_sema);

                  wiced_rtos_set_semaphore(&callback_sema);

               

                  wiced_rtos_init_semaphore(&connection_sema);

                  wiced_rtos_set_semaphore(&connection_sema);

               

                  while(1)

                  {

                      // Wait for scanning network to complete

                      wiced_rtos_get_semaphore(&callback_sema, 10000);

               

                      if (!FirstTimeConneced && !wiced_network_is_up( WICED_STA_INTERFACE ))

                      {

                          char SSIDToConnect[32] = "AP_2.4G"; //Change to connect your AP

                          char PassWord[32] = "8888888888"; //Change to connect your AP

                          wiced_result_t result = wiced_wifi_join( SSIDToConnect, WICED_SECURITY_WPA2_MIXED_PSK, (uint8_t*)PassWord, strlen(PassWord), &connection_sema ); //Change the security type according to your AP

               

                          WPRINT_APP_INFO(("AP Connect Result = %d\r\n", result));

               

                          result = wiced_rtos_get_semaphore(&connection_sema, 10000);

                          if (result != WICED_SUCCESS)

                              WPRINT_APP_INFO(("Connection semaphore return = %d\r\n", result));

               

                          if (result == WICED_SUCCESS)

                          {

               

                              if (wiced_network_up( WICED_STA_INTERFACE, WICED_USE_EXTERNAL_DHCP_SERVER, NULL ) == WICED_SUCCESS)

                              {

                                  FirstTimeConneced = 1;

                              }

                          }

                      }

               

                      if (wiced_network_is_up( WICED_STA_INTERFACE ) == WICED_TRUE)

                      {

                          wiced_network_down(WICED_STA_INTERFACE);

                          WPRINT_APP_INFO( ( "NetworkConnection is DOWN\r\n") );

                          FirstTimeConneced = 0;

                      }

               

                      print_System_memory();

                      wiced_result_t scanApiResult = wiced_wifi_scan_networks(scan_result_handler, NULL );

               

                      if (scanApiResult != WICED_SUCCESS)

                      {

                          WPRINT_APP_INFO( ( "wiced_wifi_scan_networks failed with error code = %d\r\n", scanApiResult) );

                      }

                  }

              }

               

              static void print_System_memory( void )

              {

                  volatile struct mallinfo mi = mallinfo( );

               

                  WPRINT_APP_INFO( ("\r\n-------------------SYS DBG MEM HEAP DIAGNOSTIC-----------------------\r\n") );

                  WPRINT_APP_INFO( ("malloc_info {\r\n"

                                    "\tarena:  \t%5d;\t/* total space allocated from system */\r\n"

                                    "\tordblks: \t%5d;\t/* number of non-inuse chunks */\r\n"

                                    "\tsmblks:  \t%5d;\t/* unused -- always zero */\r\n"

                                    "\thblks:  \t%5d;\t/* number of mmapped regions */\r\n"

                                    "\thblkhd:  \t%5d;\t/* total space in mmapped regions */\r\n"

                                    "\tusmblks: \t%5d;\t/* unused -- always zero */\r\n"

                                    "\tfsmblks: \t%5d;\t/* unused -- always zero */\r\n"

                                    "\tuordblks:\t%5d;\t/* total allocated space */\r\n"

                                    "\tfordblks:\t%5d;\t/* total non-inuse space */\r\n"

                                    "\tkeepcost:\t%5d;\t/* top-most, releasable (via malloc_trim) space */\r\n"

                                    "};\r\n",

                                    mi.arena,

                                    mi.ordblks,

                                    mi.smblks,

                                    mi.hblks,

                                    mi.hblkhd,

                                    mi.usmblks,

                                    mi.fsmblks,

                                    mi.uordblks,

                                    mi.fordblks,

                                    mi.keepcost ));

              }

               

              /*

              * Callback function to handle scan results

              */

              wiced_result_t scan_result_handler( wiced_scan_handler_result_t* malloced_scan_result )

              {

                  malloc_transfer_to_curr_thread( malloced_scan_result );

               

                  if (malloced_scan_result->scan_complete != WICED_TRUE)

                  {

                      wiced_scan_result_t* record = &malloced_scan_result->ap_details;

                      record->SSID.val[record->SSID.len] = 0; /* Ensure the SSID is null terminated */

               

                      WPRINT_APP_INFO( ( "%3d ", record_count ) );

                      print_scan_result(record);

                      ++record_count;

                  }

                  else

                  {

                      wiced_time_t scan_end_time;

                      wiced_time_get_time(&scan_end_time);

                      WPRINT_APP_INFO( ("\r\nScan complete in %lu milliseconds\r\n", scan_end_time - scan_start_time) );

                      wiced_rtos_set_semaphore(&callback_sema);

                  }

                  free( malloced_scan_result );

               

                  return WICED_SUCCESS;

              }

              -----------------------------------------------------------------------------


              Hope it would help.

              Seyhan