Saturday, September 25, 2010

Faster debug start time in Visual C++ 2010 by skipping symbol loading

When you start debugging in Visual Studio, Visual Studio will try to load debug symbols for your executable file and DLLs it uses. The symbol loading time is insignificant if your program uses only a couple of DLLs.
What if you have a handful of DLLs or just being paranoid? Here's how to stop loading the DLL symbols and, except of course, your executable file:
  1. In Visual Studio 2010, go to Tools->Options->Debugging->Symbols
  2. Click "Only specified modules"

    image
  3. Click "Specify modules"
  4. Clear "Always load symbols located next to modules"
  5. Click the new icon
  6. Enter your executable filename. If you don't specify your program here, breakpoints will not be hit.

    image

The idea is, most of the time, you want to debug only your executable, leaving those DLLs behind. In case you want to dig into those DLLs, just change the option to "All modules, unless excluded", or whichever way you want.
Note that these symbol options has global effect. Be careful if you work on several projects at one time. You may need to change those options back and forth.

Tuesday, July 6, 2010

C++ constructor (ctor) and destructor (dtor) review

It’s been a long time I haven’t touched C++. I only realized this when I found that I couldn’t differentiate between
Stuff *s = new Stuff;
and
Stuff s;
If you use new, some memory from the heap will be allocated for s. And the ctor of Stuff is called.

If you had too much C#, you may think that "Stuff s" does almost nothing other than declaring something. But in C++, "Stuff s" actually call the ctor of Stuff. And the memory required by s is taken from the stack. And the ctor of Stuff is called.

When do you release the memory then? If you use new, you have to delete s somewhere in the program. If you don’t use new, the dtor of Stuff will be called before the current scope exits. The call to the dtor is actually generated by the compiler.

Compile the following to see clearly what happens when you are not using new:
class Stuff {
  public:
    Stuff() {
      printf("\nctor called.");
    }
    ~Stuff() {
      printf("\ndtor called.");
    }
};

void test() {
  printf("\nInside test(). Before Stuff s.");
  Stuff s;
  printf("\nInside test(). After Stuff s.");
}

void main() {
  printf("\nInside main(). Before calling test().");
  test();
  printf("\nInside main(). After calling test().");

  printf("\n\nPress Enter to exit.");
  getchar();
}




Did you notice that dtor is called even though you did not do anything? The following disassembled output shows that the compiler generated the call to dtor.


Thursday, May 13, 2010

Restore BIOS in Gigabyte GA-8SIMLH Rev 3.x

My colleague could not use her new widescreen LCD since her built-in SiS graphics card in Gigabyte GA-8SIMLH Rev 3.x does not support the resolution. It didn’t help either, after installing the LCD driver and updating the graphics driver. So I downloaded a patched BIOS for this board to support widescreen resolutions.

I ran the Gigabyte atBIOS tool in Windows, selected the patched BIOS file, and confirm the update. At the stage when the tool showed ‘Erasing…’ or something, here came the blue screen of death. What could I do? I rebooted, only to find out that the machine could no longer boot. There was no display on the screen either.

The next step was naturally Google. This motherboard uses Award BIOS. Some pages suggested to create a boot floppy disk and put this command in autoexec.bat.
awdflash 12345678.BIN /py/sn/f/cc/r
Some pages also warned to carefully select the version of awdflash to use. I don’t know which version of awdflash that I should use, but I have a flash893 by Gigabyte. I changed the above command to flash893 but the machine still wouldn’t boot. Maybe flash893 did not understand the parameters?

I figured that 893 could be a version number. So I downloaded awd893 (awdflash version 8.93) and uses the above command line. After I rebooted, the machine did access the floppy for a while, but then nothing happen and the machine was still in bad condition.

So I ran that awd893 in a Windows 98 machine (luckily we still have an old machine with a floppy drive!) with this command
awd893 /?
I could not find /f in the output. Could this be the problem? So I modified the line in autoexec.bat to this:
awd893 bios.bin /py /sn /cc /R
I don’t know whether the parameters should be case sensitive. I just followed the cases from the /?. But the above line works!

To summarise, here’s what I did to save the old machine:
  1. Create a boot floppy disk using Windows 98:
    1. Insert the disk
    2. Open Windows Explorer.
    3. Right-click the disk
    4. Click “Format”
    5. Tick “Copy system files”
    6. Click “Start”
  2. Copy awd893 to the floppy.
  3. Copy the bios file to the floppy.
  4. Create a file called autoexec.bat in the floppy. You can use Notepad.
  5. In the file, put this line (bios.bin is the BIOS file, change it to the name of your BIOS file):
  6. awd893 bios.bin /py /sn /cc /R
  7. Save the file. When you save the file in Notepad, make sure you choose “All Files (*.*)” in “Save as type”. Name the file as autoexec.bat
  8. Insert the disk to the affected machine.
  9. Start the machine.
  10. If everything goes smoothly, the machine will flash the BIOS and reboot itself.
The final floppy disk should have the following files. You may have one extra file called drvspace.bin. I deleted it since a page said the boot disk should have minimal bootup files.
    • io.sys
    • msdos.sys
    • command.com
    • awd893.exe
    • bios.bin
    • autoexec.bat
I didn’t use the patched BIOS, I used the BIOS from Gigabyte, so the widescreen still didn’t work, cause we decided to give her a new machine.