})();
+// http://code.google.com/p/v8/issues/detail?id=427
+(function testWindowsProcessExeAndDllMapFile() {
+ function exeSymbols(exeName) {
+ return [
+ ' 0000:00000000 ___ImageBase 00400000 <linker-defined>',
+ ' 0001:00000780 ?RunMain@@YAHHQAPAD@Z 00401780 f shell.obj',
+ ' 0001:00000ac0 _main 00401ac0 f shell.obj',
+ ''
+ ].join('\r\n');
+ }
+
+ function dllSymbols(dllName) {
+ return [
+ ' 0000:00000000 ___ImageBase 01c30000 <linker-defined>',
+ ' 0001:00000780 _DllMain@12 01c31780 f libcmt:dllmain.obj',
+ ' 0001:00000ac0 ___DllMainCRTStartup 01c31ac0 f libcmt:dllcrt0.obj',
+ ''
+ ].join('\r\n');
+ }
+
+ var oldRead = read;
+
+ read = exeSymbols;
+ var exe_exe_syms = [];
+ (new WindowsCppEntriesProvider()).parseVmSymbols(
+ 'chrome.exe', 0x00400000, 0x00472000,
+ function (name, start, end) {
+ exe_exe_syms.push(Array.prototype.slice.apply(arguments, [0]));
+ });
+ assertEquals(
+ [['RunMain', 0x00401780, 0x00401ac0],
+ ['_main', 0x00401ac0, 0x00472000]],
+ exe_exe_syms, '.exe with .exe symbols');
+
+ read = dllSymbols;
+ var exe_dll_syms = [];
+ (new WindowsCppEntriesProvider()).parseVmSymbols(
+ 'chrome.exe', 0x00400000, 0x00472000,
+ function (name, start, end) {
+ exe_dll_syms.push(Array.prototype.slice.apply(arguments, [0]));
+ });
+ assertEquals(
+ [],
+ exe_dll_syms, '.exe with .dll symbols');
+
+ read = dllSymbols;
+ var dll_dll_syms = [];
+ (new WindowsCppEntriesProvider()).parseVmSymbols(
+ 'chrome.dll', 0x01c30000, 0x02b80000,
+ function (name, start, end) {
+ dll_dll_syms.push(Array.prototype.slice.apply(arguments, [0]));
+ });
+ assertEquals(
+ [['_DllMain@12', 0x01c31780, 0x01c31ac0],
+ ['___DllMainCRTStartup', 0x01c31ac0, 0x02b80000]],
+ dll_dll_syms, '.dll with .dll symbols');
+
+ read = exeSymbols;
+ var dll_exe_syms = [];
+ (new WindowsCppEntriesProvider()).parseVmSymbols(
+ 'chrome.dll', 0x01c30000, 0x02b80000,
+ function (name, start, end) {
+ dll_exe_syms.push(Array.prototype.slice.apply(arguments, [0]));
+ });
+ assertEquals(
+ [],
+ dll_exe_syms, '.dll with .exe symbols');
+
+ read = oldRead;
+})();
+
+
function CppEntriesProviderMock() {
};
inherits(WindowsCppEntriesProvider, CppEntriesProvider);
-WindowsCppEntriesProvider.FILENAME_RE = /^(.*)\.exe$/;
+WindowsCppEntriesProvider.FILENAME_RE = /^(.*)\.([^.]+)$/;
WindowsCppEntriesProvider.FUNC_RE =
- /^ 0001:[0-9a-fA-F]{8}\s+([_\?@$0-9a-zA-Z]+)\s+([0-9a-fA-F]{8}).*$/;
+ /^\s+0001:[0-9a-fA-F]{8}\s+([_\?@$0-9a-zA-Z]+)\s+([0-9a-fA-F]{8}).*$/;
+
+
+WindowsCppEntriesProvider.IMAGE_BASE_RE =
+ /^\s+0000:00000000\s+___ImageBase\s+([0-9a-fA-F]{8}).*$/;
+
+
+// This is almost a constant on Windows.
+WindowsCppEntriesProvider.EXE_IMAGE_BASE = 0x00400000;
WindowsCppEntriesProvider.prototype.loadSymbols = function(libName) {
var fileNameFields = libName.match(WindowsCppEntriesProvider.FILENAME_RE);
- // Only try to load symbols for the .exe file.
if (!fileNameFields) return;
var mapFileName = fileNameFields[1] + '.map';
- this.symbols = readFile(mapFileName);
+ this.moduleType_ = fileNameFields[2].toLowerCase();
+ try {
+ this.symbols = read(mapFileName);
+ } catch (e) {
+ // If .map file cannot be found let's not panic.
+ this.symbols = '';
+ }
};
var line = this.symbols.substring(this.parsePos, lineEndPos);
this.parsePos = lineEndPos + 2;
+
+ // Image base entry is above all other symbols, so we can just
+ // terminate parsing.
+ var imageBaseFields = line.match(WindowsCppEntriesProvider.IMAGE_BASE_RE);
+ if (imageBaseFields) {
+ var imageBase = parseInt(imageBaseFields[1], 16);
+ if ((this.moduleType_ == 'exe') !=
+ (imageBase == WindowsCppEntriesProvider.EXE_IMAGE_BASE)) {
+ return false;
+ }
+ }
+
var fields = line.match(WindowsCppEntriesProvider.FUNC_RE);
return fields ?
{ name: this.unmangleName(fields[1]), start: parseInt(fields[2], 16) } :