Thursday, July 5, 2012

System Debuggig for WinCE (ToolHelp and more)

With my first post after like a quarter of a decade, I'll go in depth to trick and a box of tools that'll help you debug CE if you don't what really is going on.

Well in MSDN there is this box of tools known as ToolHelp Library it has a lot of functions that would help you debug devices and gather system data like module info, process info, and memory stuff. Yes I know you can do this with Remote Tools in Platform builder. But for Remote Tools to work you have to connect that device via KITL. So what if you have an issue that occurs on only in 2 out of 10 units? Well the best way for that to work is to make a standalone application that you can run 10 devices and collects what you need.

These functions can be found here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686832%28v=vs.85%29.aspx

This is documented in MSDN, so you guys can check the definitions there. What I'll share are tricks how to use these functions.

1.) Make sure your project has include these headers
#include
#include


These files are normally declared in PUBLIC\COMMON\OAK\INC. So make sure you point your project to include this directory to your build.
2.) Make sure your project include PUBLIC\COMMON\OAK\LIB\ARMV4I\RETAIL\toolhelp.lib in your additional dependencies.
3.) I'll share a code snippet here from an app I created to monitor my system. Some variable declaration were omitted so you may fill in the blanks yourself. :)

====================================================================
Here's a sample for gathering all the running processes
 // Get the list of running processes
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS|TH32CS_SNAPNOHEAPS,NULL);
PROCESSENTRY32 Tmp;
               
if (hSnapShot != INVALID_HANDLE_VALUE)
{
   Tmp.dwSize = sizeof(PROCESSENTRY32);
     if (Process32First(hSnapShot,&Tmp))
     {           
        do {
                 AddProcessToList(&Tmp); // This can be your function that write the processes to and array or logs the process info immediately.
        }while(Process32Next(hSnapShot,&Tmp));
     }

     CloseToolhelp32Snapshot(hSnapShot);

  }

==================================================================

Here's a sample how I try to create a list of processes and log them to a file.

    bool fFound = FALSE;
    DWORD index = 0;


    while(index < gProcessCount)
    {
        if(gProcessList[index].id == proc->th32ProcessID)
        {
            memcpy(gProcessList[index].name,proc->szExeFile,sizeof(TCHAR) * MAX_PATH);
            fFound = TRUE;
        }
        index++;
    }
    if(fFound == FALSE)
    {
      
        gProcessList[index].id = proc->th32ProcessID;
        memcpy(gProcessList[index].name,proc->szExeFile,sizeof(TCHAR) * MAX_PATH);
        // New entry so we increment
        gProcessCount = index + 1;
    }

============================================================
I created my own list structure to like this.

struct List
{
    DWORD id;
    DWORD value;
    bool gotData;
    TCHAR name[MAX_PATH];
};
struct List gProcessList[100] = {0};
=============================================================
Here's how I log this to a file:

    DWORD index = 0;
    FILE *fProcLog;
    // Open log file
    fProcLog = fopen(gProcLogFilename, "a");
    if(fProcLog){
        // print log number
        fprintf(fProcLog, "\nLog %8d:", logCount);
        while(index < gProcessCount)
        {
            // Print module name
            fwprintf(fProcLog,L"%s:%08X:%8d:",gProcessList[index].name,gProcessList[index].id,(DWORD)gProcessList[index].gotData * 100);

            gProcessList[index].gotData = FALSE;
            index++;
        }
    }
    fclose(fProcLog);

No comments: