@@ -1326,22 +1326,27 @@ struct CodeViewRecord70 {
13261326};
13271327
13281328/**
1329- * Extract PDB debug info (GUID and age ) from a module in another process
1330- * Uses ReadProcessMemory to read PE headers from the crashed process
1329+ * Extract PDB debug info (GUID, age, and filename ) from a module in another
1330+ * process. Uses ReadProcessMemory to read PE headers from the crashed process.
13311331 *
13321332 * @param hProcess Handle to the crashed process
13331333 * @param module_base Base address of the module in the crashed process
13341334 * @param uuid Output: 16-byte PDB GUID (set to zeros on failure)
13351335 * @param pdb_age Output: PDB age value (set to 0 on failure)
1336+ * @param pdb_name Output: PDB filename buffer (set to empty on failure)
1337+ * @param pdb_name_size Size of pdb_name buffer
13361338 * @return true if PDB info was successfully extracted
13371339 */
13381340static bool
1339- extract_pdb_info_from_process (
1340- HANDLE hProcess , uint64_t module_base , uint8_t * uuid , uint32_t * pdb_age )
1341+ extract_pdb_info_from_process (HANDLE hProcess , uint64_t module_base ,
1342+ uint8_t * uuid , uint32_t * pdb_age , char * pdb_name , size_t pdb_name_size )
13411343{
1342- // Initialize outputs to zero
1344+ // Initialize outputs to zero/empty
13431345 memset (uuid , 0 , 16 );
13441346 * pdb_age = 0 ;
1347+ if (pdb_name && pdb_name_size > 0 ) {
1348+ pdb_name [0 ] = '\0' ;
1349+ }
13451350
13461351 if (!module_base ) {
13471352 return false;
@@ -1418,7 +1423,28 @@ extract_pdb_info_from_process(
14181423 // Extract age (bytes 20-23)
14191424 memcpy (pdb_age , cv_header + 20 , sizeof (* pdb_age ));
14201425
1421- SENTRY_DEBUGF ("Extracted PDB info: age=%u" , * pdb_age );
1426+ // Extract PDB filename (variable length, null-terminated, starts at
1427+ // byte 24) The filename can be up to (SizeOfData - 24) bytes
1428+ if (pdb_name && pdb_name_size > 0 ) {
1429+ size_t max_filename_len = pdb_name_size - 1 ;
1430+ if (debug_entry .SizeOfData > 24 ) {
1431+ size_t available = debug_entry .SizeOfData - 24 ;
1432+ if (available < max_filename_len ) {
1433+ max_filename_len = available ;
1434+ }
1435+ }
1436+ uint64_t filename_addr = cv_addr + 24 ;
1437+ SIZE_T filename_read ;
1438+ if (ReadProcessMemory (hProcess , (LPCVOID )(uintptr_t )filename_addr ,
1439+ pdb_name , max_filename_len , & filename_read )) {
1440+ pdb_name [filename_read ] = '\0' ;
1441+ // Ensure null termination within buffer
1442+ pdb_name [pdb_name_size - 1 ] = '\0' ;
1443+ }
1444+ }
1445+
1446+ SENTRY_DEBUGF ("Extracted PDB info: age=%u, pdb=%s" , * pdb_age ,
1447+ pdb_name ? pdb_name : "(null)" );
14221448 return true;
14231449 }
14241450
@@ -1476,9 +1502,9 @@ capture_modules_from_process(sentry_crash_context_t *ctx)
14761502 strncpy (mod -> name , modName , sizeof (mod -> name ) - 1 );
14771503 mod -> name [sizeof (mod -> name ) - 1 ] = '\0' ;
14781504
1479- // Extract PDB GUID and age from PE debug directory
1480- extract_pdb_info_from_process (
1481- hProcess , mod -> base_address , mod -> uuid , & mod -> pdb_age );
1505+ // Extract PDB GUID, age, and filename from PE debug directory
1506+ extract_pdb_info_from_process (hProcess , mod -> base_address , mod -> uuid ,
1507+ & mod -> pdb_age , mod -> pdb_name , sizeof ( mod -> pdb_name ) );
14821508
14831509 SENTRY_DEBUGF ("Captured module: %s base=0x%llx size=0x%llx pdb_age=%u" ,
14841510 mod -> name , (unsigned long long )mod -> base_address ,
@@ -1775,12 +1801,12 @@ build_native_crash_event(const sentry_crash_context_t *ctx,
17751801
17761802#if defined(SENTRY_PLATFORM_WINDOWS )
17771803 // Set code_id for PE modules (TimeDateStamp + SizeOfImage)
1778- // This helps Sentry identify the module without full debug info
1804+ // Format: lowercase hex to match minidump format
17791805 if (mod -> name [0 ]) {
17801806 DWORD timestamp = get_pe_timestamp (mod -> name );
17811807 if (timestamp != 0 ) {
17821808 char code_id_buf [32 ];
1783- snprintf (code_id_buf , sizeof (code_id_buf ), "%08X %x" ,
1809+ snprintf (code_id_buf , sizeof (code_id_buf ), "%x %x" ,
17841810 (unsigned int )timestamp , (unsigned int )mod -> size );
17851811 sentry_value_set_by_key (
17861812 image , "code_id" , sentry_value_new_string (code_id_buf ));
@@ -1805,6 +1831,12 @@ build_native_crash_event(const sentry_crash_context_t *ctx,
18051831 sentry_value_set_by_key (
18061832 image , "debug_id" , sentry_value_new_string (debug_id_buf ));
18071833 }
1834+
1835+ // Set debug_file (path to PDB file for symbolication)
1836+ if (mod -> pdb_name [0 ]) {
1837+ sentry_value_set_by_key (image , "debug_file" ,
1838+ sentry_value_new_string (mod -> pdb_name ));
1839+ }
18081840#else
18091841 // Set debug_id from UUID (macOS/Linux)
18101842 sentry_uuid_t uuid
0 commit comments