Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: src/processor/minidump.cc

Issue 1675413002: Change MDCVInfoELF into something usable. (Closed) Base URL: https://chromium.googlesource.com/breakpad/breakpad.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2010 Google Inc. 1 // Copyright (c) 2010 Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 1835 matching lines...) Expand 10 before | Expand all | Expand 10 after
1846 case MD_OS_WIN32_WINDOWS: { 1846 case MD_OS_WIN32_WINDOWS: {
1847 // Use the same format that the MS symbol server uses in filesystem 1847 // Use the same format that the MS symbol server uses in filesystem
1848 // hierarchies. 1848 // hierarchies.
1849 char identifier_string[17]; 1849 char identifier_string[17];
1850 snprintf(identifier_string, sizeof(identifier_string), "%08X%x", 1850 snprintf(identifier_string, sizeof(identifier_string), "%08X%x",
1851 module_.time_date_stamp, module_.size_of_image); 1851 module_.time_date_stamp, module_.size_of_image);
1852 identifier = identifier_string; 1852 identifier = identifier_string;
1853 break; 1853 break;
1854 } 1854 }
1855 1855
1856 case MD_OS_ANDROID:
1857 case MD_OS_LINUX: {
1858 // If ELF CodeView data is present, return the debug id.
1859 if (cv_record_ && cv_record_signature_ == MD_CVINFOELF_SIGNATURE) {
1860 const MDCVInfoELF* cv_record_elf =
1861 reinterpret_cast<const MDCVInfoELF*>(&(*cv_record_)[0]);
1862 assert(cv_record_elf->cv_signature == MD_CVINFOELF_SIGNATURE);
1863
1864 for (unsigned int build_id_index = 0;
1865 build_id_index < (cv_record_->size() - MDCVInfoELF_minsize);
1866 ++build_id_index) {
1867 char byte[3];
Mark Mentovai 2016/02/09 19:27:05 build_id[build_id_index] is the byte, this is a st
1868 snprintf(byte, sizeof(byte), "%02x",
1869 cv_record_elf->build_id[build_id_index]);
1870 identifier += byte;
1871 }
1872 break;
1873 }
1874 // Otherwise fall through to the case below.
1875 }
1876
1856 case MD_OS_MAC_OS_X: 1877 case MD_OS_MAC_OS_X:
1857 case MD_OS_IOS: 1878 case MD_OS_IOS:
1858 case MD_OS_SOLARIS: 1879 case MD_OS_SOLARIS:
1859 case MD_OS_ANDROID:
1860 case MD_OS_LINUX:
1861 case MD_OS_NACL: 1880 case MD_OS_NACL:
1862 case MD_OS_PS3: { 1881 case MD_OS_PS3: {
1863 // TODO(mmentovai): support uuid extension if present, otherwise fall 1882 // TODO(mmentovai): support uuid extension if present, otherwise fall
1864 // back to version (from LC_ID_DYLIB?), otherwise fall back to something 1883 // back to version (from LC_ID_DYLIB?), otherwise fall back to something
1865 // else. 1884 // else.
1866 identifier = "id"; 1885 identifier = "id";
1867 break; 1886 break;
1868 } 1887 }
1869 1888
1870 default: { 1889 default: {
(...skipping 30 matching lines...) Expand all
1901 // GetCVRecord guarantees pdb_file_name is null-terminated. 1920 // GetCVRecord guarantees pdb_file_name is null-terminated.
1902 file = reinterpret_cast<const char*>(cv_record_70->pdb_file_name); 1921 file = reinterpret_cast<const char*>(cv_record_70->pdb_file_name);
1903 } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { 1922 } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) {
1904 // It's actually an MDCVInfoPDB20 structure. 1923 // It's actually an MDCVInfoPDB20 structure.
1905 const MDCVInfoPDB20* cv_record_20 = 1924 const MDCVInfoPDB20* cv_record_20 =
1906 reinterpret_cast<const MDCVInfoPDB20*>(&(*cv_record_)[0]); 1925 reinterpret_cast<const MDCVInfoPDB20*>(&(*cv_record_)[0]);
1907 assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); 1926 assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE);
1908 1927
1909 // GetCVRecord guarantees pdb_file_name is null-terminated. 1928 // GetCVRecord guarantees pdb_file_name is null-terminated.
1910 file = reinterpret_cast<const char*>(cv_record_20->pdb_file_name); 1929 file = reinterpret_cast<const char*>(cv_record_20->pdb_file_name);
1930 } else if (cv_record_signature_ == MD_CVINFOELF_SIGNATURE) {
1931 // It's actually an MDCVInfoELF structure.
1932 const MDCVInfoELF* cv_record_elf =
1933 reinterpret_cast<const MDCVInfoELF*>(&(*cv_record_)[0]);
1934 assert(cv_record_elf->cv_signature == MD_CVINFOELF_SIGNATURE);
1935
1936 // For MDCVInfoELF, the debug file is the code file.
1937 file = *name_;
1911 } 1938 }
1912 1939
1913 // If there's a CodeView record but it doesn't match a known signature, 1940 // If there's a CodeView record but it doesn't match a known signature,
1914 // try the miscellaneous record. 1941 // try the miscellaneous record.
1915 } 1942 }
1916 1943
1917 if (file.empty()) { 1944 if (file.empty()) {
1918 // No usable CodeView record. Try the miscellaneous debug record. 1945 // No usable CodeView record. Try the miscellaneous debug record.
1919 if (misc_record_) { 1946 if (misc_record_) {
1920 const MDImageDebugMisc* misc_record = 1947 const MDImageDebugMisc* misc_record =
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1952 } 1979 }
1953 } 1980 }
1954 1981
1955 // Relatively common case 1982 // Relatively common case
1956 BPLOG_IF(INFO, file.empty()) << "MinidumpModule could not determine " 1983 BPLOG_IF(INFO, file.empty()) << "MinidumpModule could not determine "
1957 "debug_file for " << *name_; 1984 "debug_file for " << *name_;
1958 1985
1959 return file; 1986 return file;
1960 } 1987 }
1961 1988
1989 static string guid_and_age_to_debug_id(const MDGUID& guid,
1990 uint32_t age) {
1991 char identifier_string[41];
1992 snprintf(identifier_string, sizeof(identifier_string),
1993 "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%x",
1994 guid.data1,
1995 guid.data2,
1996 guid.data3,
1997 guid.data4[0],
1998 guid.data4[1],
1999 guid.data4[2],
2000 guid.data4[3],
2001 guid.data4[4],
2002 guid.data4[5],
2003 guid.data4[6],
2004 guid.data4[7],
2005 age);
2006 return identifier_string;
2007 }
1962 2008
1963 string MinidumpModule::debug_identifier() const { 2009 string MinidumpModule::debug_identifier() const {
1964 if (!valid_) { 2010 if (!valid_) {
1965 BPLOG(ERROR) << "Invalid MinidumpModule for debug_identifier"; 2011 BPLOG(ERROR) << "Invalid MinidumpModule for debug_identifier";
1966 return ""; 2012 return "";
1967 } 2013 }
1968 2014
1969 if (!has_debug_info_) 2015 if (!has_debug_info_)
1970 return ""; 2016 return "";
1971 2017
1972 string identifier; 2018 string identifier;
1973 2019
1974 // Use the CodeView record if present. 2020 // Use the CodeView record if present.
1975 if (cv_record_) { 2021 if (cv_record_) {
1976 if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) { 2022 if (cv_record_signature_ == MD_CVINFOPDB70_SIGNATURE) {
1977 // It's actually an MDCVInfoPDB70 structure. 2023 // It's actually an MDCVInfoPDB70 structure.
1978 const MDCVInfoPDB70* cv_record_70 = 2024 const MDCVInfoPDB70* cv_record_70 =
1979 reinterpret_cast<const MDCVInfoPDB70*>(&(*cv_record_)[0]); 2025 reinterpret_cast<const MDCVInfoPDB70*>(&(*cv_record_)[0]);
1980 assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE); 2026 assert(cv_record_70->cv_signature == MD_CVINFOPDB70_SIGNATURE);
1981 2027
1982 // Use the same format that the MS symbol server uses in filesystem 2028 // Use the same format that the MS symbol server uses in filesystem
1983 // hierarchies. 2029 // hierarchies.
1984 char identifier_string[41]; 2030 identifier = guid_and_age_to_debug_id(cv_record_70->signature,
1985 snprintf(identifier_string, sizeof(identifier_string), 2031 cv_record_70->age);
1986 "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%x",
1987 cv_record_70->signature.data1,
1988 cv_record_70->signature.data2,
1989 cv_record_70->signature.data3,
1990 cv_record_70->signature.data4[0],
1991 cv_record_70->signature.data4[1],
1992 cv_record_70->signature.data4[2],
1993 cv_record_70->signature.data4[3],
1994 cv_record_70->signature.data4[4],
1995 cv_record_70->signature.data4[5],
1996 cv_record_70->signature.data4[6],
1997 cv_record_70->signature.data4[7],
1998 cv_record_70->age);
1999 identifier = identifier_string;
2000 } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { 2032 } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) {
2001 // It's actually an MDCVInfoPDB20 structure. 2033 // It's actually an MDCVInfoPDB20 structure.
2002 const MDCVInfoPDB20* cv_record_20 = 2034 const MDCVInfoPDB20* cv_record_20 =
2003 reinterpret_cast<const MDCVInfoPDB20*>(&(*cv_record_)[0]); 2035 reinterpret_cast<const MDCVInfoPDB20*>(&(*cv_record_)[0]);
2004 assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE); 2036 assert(cv_record_20->cv_header.signature == MD_CVINFOPDB20_SIGNATURE);
2005 2037
2006 // Use the same format that the MS symbol server uses in filesystem 2038 // Use the same format that the MS symbol server uses in filesystem
2007 // hierarchies. 2039 // hierarchies.
2008 char identifier_string[17]; 2040 char identifier_string[17];
2009 snprintf(identifier_string, sizeof(identifier_string), 2041 snprintf(identifier_string, sizeof(identifier_string),
2010 "%08X%x", cv_record_20->signature, cv_record_20->age); 2042 "%08X%x", cv_record_20->signature, cv_record_20->age);
2011 identifier = identifier_string; 2043 identifier = identifier_string;
2044 } else if (cv_record_signature_ == MD_CVINFOELF_SIGNATURE) {
2045 // It's actually an MDCVInfoELF structure.
2046 const MDCVInfoELF* cv_record_elf =
2047 reinterpret_cast<const MDCVInfoELF*>(&(*cv_record_)[0]);
2048 assert(cv_record_elf->cv_signature == MD_CVINFOELF_SIGNATURE);
2049
2050 // For backwards-compatibility, stuff as many bytes as will fit into
2051 // a MDGUID and use the MS symbol server format as MDCVInfoPDB70 does
2052 // with age = 0. Historically Breakpad would do this during dump
2053 // writing to fit the build id data into a MDCVInfoPDB70 struct.
2054 // The full build id is available by calling code_identifier.
2055 MDGUID guid = {0};
2056 memcpy(&guid, &cv_record_elf->build_id,
2057 cv_record_->size() - MDCVInfoELF_minsize);
2058 identifier = guid_and_age_to_debug_id(guid, 0);
2012 } 2059 }
2013 } 2060 }
2014 2061
2015 // TODO(mmentovai): if there's no usable CodeView record, there might be a 2062 // TODO(mmentovai): if there's no usable CodeView record, there might be a
2016 // miscellaneous debug record. It only carries a filename, though, and no 2063 // miscellaneous debug record. It only carries a filename, though, and no
2017 // identifier. I'm not sure what the right thing to do for the identifier 2064 // identifier. I'm not sure what the right thing to do for the identifier
2018 // is in that case, but I don't expect to find many modules without a 2065 // is in that case, but I don't expect to find many modules without a
2019 // CodeView record (or some other Breakpad extension structure in place of 2066 // CodeView record (or some other Breakpad extension structure in place of
2020 // a CodeView record). Treat it as an error (empty identifier) for now. 2067 // a CodeView record). Treat it as an error (empty identifier) for now.
2021 2068
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
2160 // quantities. (It's a path, is it UTF-8?) 2207 // quantities. (It's a path, is it UTF-8?)
2161 } 2208 }
2162 2209
2163 // The last field of either structure is null-terminated 8-bit character 2210 // The last field of either structure is null-terminated 8-bit character
2164 // data. Ensure that it's null-terminated. 2211 // data. Ensure that it's null-terminated.
2165 if ((*cv_record)[module_.cv_record.data_size - 1] != '\0') { 2212 if ((*cv_record)[module_.cv_record.data_size - 1] != '\0') {
2166 BPLOG(ERROR) << "MindumpModule CodeView2 record string is not " 2213 BPLOG(ERROR) << "MindumpModule CodeView2 record string is not "
2167 "0-terminated"; 2214 "0-terminated";
2168 return NULL; 2215 return NULL;
2169 } 2216 }
2217 } else if (signature == MD_CVINFOELF_SIGNATURE) {
2218 // Now that the structure type is known, recheck the size.
2219 if (MDCVInfoELF_minsize > module_.cv_record.data_size) {
2220 BPLOG(ERROR) << "MinidumpModule CodeViewELF record size mismatch, " <<
2221 MDCVInfoELF_minsize << " > " <<
2222 module_.cv_record.data_size;
2223 return NULL;
2224 }
2225 // There's nothing to swap in CVInfoELF, it's just raw bytes.
2170 } 2226 }
2171 2227
2172 // If the signature doesn't match something above, it's not something 2228 // If the signature doesn't match something above, it's not something
2173 // that Breakpad can presently handle directly. Because some modules in 2229 // that Breakpad can presently handle directly. Because some modules in
2174 // the wild contain such CodeView records as MD_CVINFOCV50_SIGNATURE, 2230 // the wild contain such CodeView records as MD_CVINFOCV50_SIGNATURE,
2175 // don't bail out here - allow the data to be returned to the user, 2231 // don't bail out here - allow the data to be returned to the user,
2176 // although byte-swapping can't be done. 2232 // although byte-swapping can't be done.
2177 2233
2178 // Store the vector type because that's how storage was allocated, but 2234 // Store the vector type because that's how storage was allocated, but
2179 // return it casted to uint8_t*. 2235 // return it casted to uint8_t*.
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
2360 cv_record_20->cv_header.signature); 2416 cv_record_20->cv_header.signature);
2361 printf(" (cv_record).cv_header.offset = 0x%x\n", 2417 printf(" (cv_record).cv_header.offset = 0x%x\n",
2362 cv_record_20->cv_header.offset); 2418 cv_record_20->cv_header.offset);
2363 printf(" (cv_record).signature = 0x%x %s\n", 2419 printf(" (cv_record).signature = 0x%x %s\n",
2364 cv_record_20->signature, 2420 cv_record_20->signature,
2365 TimeTToUTCString(cv_record_20->signature).c_str()); 2421 TimeTToUTCString(cv_record_20->signature).c_str());
2366 printf(" (cv_record).age = %d\n", 2422 printf(" (cv_record).age = %d\n",
2367 cv_record_20->age); 2423 cv_record_20->age);
2368 printf(" (cv_record).pdb_file_name = \"%s\"\n", 2424 printf(" (cv_record).pdb_file_name = \"%s\"\n",
2369 cv_record_20->pdb_file_name); 2425 cv_record_20->pdb_file_name);
2426 } else if (cv_record_signature_ == MD_CVINFOELF_SIGNATURE) {
2427 const MDCVInfoELF* cv_record_elf =
2428 reinterpret_cast<const MDCVInfoELF*>(cv_record);
2429 assert(cv_record_elf->cv_signature == MD_CVINFOELF_SIGNATURE);
2430
2431 printf(" (cv_record).cv_signature = 0x%x\n",
2432 cv_record_elf->cv_signature);
2433 printf(" (cv_record).build_id = ");
2434 for (unsigned int build_id_index = 0;
2435 build_id_index < (cv_record_size - MDCVInfoELF_minsize);
2436 ++build_id_index) {
2437 printf("%02x", cv_record_elf->build_id[build_id_index]);
2438 }
2439 printf("\n");
2370 } else { 2440 } else {
2371 printf(" (cv_record) = "); 2441 printf(" (cv_record) = ");
2372 for (unsigned int cv_byte_index = 0; 2442 for (unsigned int cv_byte_index = 0;
2373 cv_byte_index < cv_record_size; 2443 cv_byte_index < cv_record_size;
2374 ++cv_byte_index) { 2444 ++cv_byte_index) {
2375 printf("%02x", cv_record[cv_byte_index]); 2445 printf("%02x", cv_record[cv_byte_index]);
2376 } 2446 }
2377 printf("\n"); 2447 printf("\n");
2378 } 2448 }
2379 } else { 2449 } else {
(...skipping 2406 matching lines...) Expand 10 before | Expand all | Expand 10 after
4786 return NULL; 4856 return NULL;
4787 } 4857 }
4788 4858
4789 *stream = new_stream.release(); 4859 *stream = new_stream.release();
4790 info->stream = *stream; 4860 info->stream = *stream;
4791 return *stream; 4861 return *stream;
4792 } 4862 }
4793 4863
4794 4864
4795 } // namespace google_breakpad 4865 } // namespace google_breakpad
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698