2020#include " lldb/Symbol/LocateSymbolFile.h"
2121#include " lldb/Symbol/ObjectFile.h"
2222#include " lldb/Target/Target.h"
23+ #include " lldb/Utility/Reproducer.h"
2324#include " lldb/Utility/StreamString.h"
2425#include " lldb/Utility/Timer.h"
2526
@@ -145,6 +146,11 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
145146 }
146147
147148 if (dsym_fspec) {
149+ // Compute dSYM root.
150+ std::string dsym_root = dsym_fspec.GetPath ();
151+ const size_t pos = dsym_root.find (" /Contents/Resources/" );
152+ dsym_root = pos != std::string::npos ? dsym_root.substr (0 , pos) : " " ;
153+
148154 DataBufferSP dsym_file_data_sp;
149155 lldb::offset_t dsym_file_data_offset = 0 ;
150156 dsym_objfile_sp =
@@ -154,136 +160,132 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
154160 if (UUIDsMatch (module_sp.get (), dsym_objfile_sp.get (), feedback_strm)) {
155161 // We need a XML parser if we hope to parse a plist...
156162 if (XMLDocument::XMLEnabled ()) {
157- char dsym_path[PATH_MAX];
158- if (module_sp->GetSourceMappingList ().IsEmpty () &&
159- dsym_fspec.GetPath (dsym_path, sizeof (dsym_path))) {
163+ if (module_sp->GetSourceMappingList ().IsEmpty ()) {
160164 lldb_private::UUID dsym_uuid = dsym_objfile_sp->GetUUID ();
161165 if (dsym_uuid) {
162166 std::string uuid_str = dsym_uuid.GetAsString ();
163- if (!uuid_str.empty ()) {
164- char *resources = strstr (dsym_path, " /Contents/Resources/" );
165- if (resources) {
166- char dsym_uuid_plist_path[PATH_MAX];
167- resources[strlen (" /Contents/Resources/" )] = ' \0 ' ;
168- snprintf (dsym_uuid_plist_path, sizeof (dsym_uuid_plist_path),
169- " %s%s.plist" , dsym_path, uuid_str.c_str ());
170- FileSpec dsym_uuid_plist_spec (dsym_uuid_plist_path);
171- if (FileSystem::Instance ().Exists (dsym_uuid_plist_spec)) {
172- ApplePropertyList plist (dsym_uuid_plist_path);
173- if (plist) {
174- std::string DBGBuildSourcePath;
175- std::string DBGSourcePath;
176-
177- // DBGSourcePathRemapping is a dictionary in the plist
178- // with keys which are DBGBuildSourcePath file paths and
179- // values which are DBGSourcePath file paths
180-
181- StructuredData::ObjectSP plist_sp =
182- plist.GetStructuredData ();
183- if (plist_sp.get () && plist_sp->GetAsDictionary () &&
184- plist_sp->GetAsDictionary ()->HasKey (
185- " DBGSourcePathRemapping" ) &&
186- plist_sp->GetAsDictionary ()
187- ->GetValueForKey (" DBGSourcePathRemapping" )
188- ->GetAsDictionary ()) {
189-
190- // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping.
191- // If DBGVersion 2, strip last two components of path remappings from
192- // entries to fix an issue with a specific set of
193- // DBGSourcePathRemapping entries that lldb worked
194- // with.
195- // If DBGVersion 3, trust & use the source path remappings as-is.
196- //
197-
198- bool new_style_source_remapping_dictionary = false ;
199- bool do_truncate_remapping_names = false ;
200- std::string original_DBGSourcePath_value =
201- DBGSourcePath;
202- if (plist_sp->GetAsDictionary ()->HasKey (" DBGVersion" )) {
203- std::string version_string =
204- std::string (plist_sp->GetAsDictionary ()
205- ->GetValueForKey (" DBGVersion" )
206- ->GetStringValue (" " ));
207- if (!version_string.empty () &&
208- isdigit (version_string[0 ])) {
209- int version_number = atoi (version_string.c_str ());
210- if (version_number > 1 ) {
211- new_style_source_remapping_dictionary = true ;
212- }
213- if (version_number == 2 ) {
214- do_truncate_remapping_names = true ;
215- }
167+ if (!uuid_str.empty () && !dsym_root.empty ()) {
168+ char dsym_uuid_plist_path[PATH_MAX];
169+ snprintf (dsym_uuid_plist_path, sizeof (dsym_uuid_plist_path),
170+ " %s/Contents/Resources/%s.plist" , dsym_root.c_str (),
171+ uuid_str.c_str ());
172+ FileSpec dsym_uuid_plist_spec (dsym_uuid_plist_path);
173+ if (FileSystem::Instance ().Exists (dsym_uuid_plist_spec)) {
174+ ApplePropertyList plist (dsym_uuid_plist_path);
175+ if (plist) {
176+ std::string DBGBuildSourcePath;
177+ std::string DBGSourcePath;
178+
179+ // DBGSourcePathRemapping is a dictionary in the plist
180+ // with keys which are DBGBuildSourcePath file paths and
181+ // values which are DBGSourcePath file paths
182+
183+ StructuredData::ObjectSP plist_sp =
184+ plist.GetStructuredData ();
185+ if (plist_sp.get () && plist_sp->GetAsDictionary () &&
186+ plist_sp->GetAsDictionary ()->HasKey (
187+ " DBGSourcePathRemapping" ) &&
188+ plist_sp->GetAsDictionary ()
189+ ->GetValueForKey (" DBGSourcePathRemapping" )
190+ ->GetAsDictionary ()) {
191+
192+ // If DBGVersion 1 or DBGVersion missing, ignore
193+ // DBGSourcePathRemapping. If DBGVersion 2, strip last two
194+ // components of path remappings from
195+ // entries to fix an issue with a
196+ // specific set of DBGSourcePathRemapping
197+ // entries that lldb worked with.
198+ // If DBGVersion 3, trust & use the source path remappings
199+ // as-is.
200+ //
201+
202+ bool new_style_source_remapping_dictionary = false ;
203+ bool do_truncate_remapping_names = false ;
204+ std::string original_DBGSourcePath_value = DBGSourcePath;
205+ if (plist_sp->GetAsDictionary ()->HasKey (" DBGVersion" )) {
206+ std::string version_string =
207+ std::string (plist_sp->GetAsDictionary ()
208+ ->GetValueForKey (" DBGVersion" )
209+ ->GetStringValue (" " ));
210+ if (!version_string.empty () &&
211+ isdigit (version_string[0 ])) {
212+ int version_number = atoi (version_string.c_str ());
213+ if (version_number > 1 ) {
214+ new_style_source_remapping_dictionary = true ;
215+ }
216+ if (version_number == 2 ) {
217+ do_truncate_remapping_names = true ;
216218 }
217219 }
220+ }
218221
219- StructuredData::Dictionary *remappings_dict =
220- plist_sp->GetAsDictionary ()
221- ->GetValueForKey (" DBGSourcePathRemapping" )
222- ->GetAsDictionary ();
223- remappings_dict->ForEach (
224- [&module_sp, new_style_source_remapping_dictionary,
225- original_DBGSourcePath_value, do_truncate_remapping_names](
226- ConstString key,
227- StructuredData::Object *object) -> bool {
228- if (object && object->GetAsString ()) {
229-
230- // key is DBGBuildSourcePath
231- // object is DBGSourcePath
232- std::string DBGSourcePath =
233- std::string (object->GetStringValue ());
234- if (!new_style_source_remapping_dictionary &&
235- !original_DBGSourcePath_value.empty ()) {
236- DBGSourcePath = original_DBGSourcePath_value;
237- }
238- if (DBGSourcePath[0 ] == ' ~' ) {
239- FileSpec resolved_source_path (
240- DBGSourcePath.c_str ());
241- FileSystem::Instance ().Resolve (
242- resolved_source_path);
243- DBGSourcePath =
244- resolved_source_path.GetPath ();
245- }
222+ StructuredData::Dictionary *remappings_dict =
223+ plist_sp->GetAsDictionary ()
224+ ->GetValueForKey (" DBGSourcePathRemapping" )
225+ ->GetAsDictionary ();
226+ remappings_dict->ForEach (
227+ [&module_sp, new_style_source_remapping_dictionary,
228+ original_DBGSourcePath_value,
229+ do_truncate_remapping_names](
230+ ConstString key,
231+ StructuredData::Object *object) -> bool {
232+ if (object && object->GetAsString ()) {
233+
234+ // key is DBGBuildSourcePath
235+ // object is DBGSourcePath
236+ std::string DBGSourcePath =
237+ std::string (object->GetStringValue ());
238+ if (!new_style_source_remapping_dictionary &&
239+ !original_DBGSourcePath_value.empty ()) {
240+ DBGSourcePath = original_DBGSourcePath_value;
241+ }
242+ if (DBGSourcePath[0 ] == ' ~' ) {
243+ FileSpec resolved_source_path (
244+ DBGSourcePath.c_str ());
245+ FileSystem::Instance ().Resolve (
246+ resolved_source_path);
247+ DBGSourcePath = resolved_source_path.GetPath ();
248+ }
249+ module_sp->GetSourceMappingList ().Append (
250+ key, ConstString (DBGSourcePath), true );
251+ // With version 2 of DBGSourcePathRemapping, we
252+ // can chop off the last two filename parts
253+ // from the source remapping and get a more
254+ // general source remapping that still works.
255+ // Add this as another option in addition to
256+ // the full source path remap.
257+ if (do_truncate_remapping_names) {
258+ FileSpec build_path (key.AsCString ());
259+ FileSpec source_path (DBGSourcePath.c_str ());
260+ build_path.RemoveLastPathComponent ();
261+ build_path.RemoveLastPathComponent ();
262+ source_path.RemoveLastPathComponent ();
263+ source_path.RemoveLastPathComponent ();
246264 module_sp->GetSourceMappingList ().Append (
247- key, ConstString (DBGSourcePath), true );
248- // With version 2 of DBGSourcePathRemapping, we
249- // can chop off the last two filename parts
250- // from the source remapping and get a more
251- // general source remapping that still works.
252- // Add this as another option in addition to
253- // the full source path remap.
254- if (do_truncate_remapping_names) {
255- FileSpec build_path (key.AsCString ());
256- FileSpec source_path (DBGSourcePath.c_str ());
257- build_path.RemoveLastPathComponent ();
258- build_path.RemoveLastPathComponent ();
259- source_path.RemoveLastPathComponent ();
260- source_path.RemoveLastPathComponent ();
261- module_sp->GetSourceMappingList ().Append (
262- ConstString (build_path.GetPath ().c_str ()),
263- ConstString (source_path.GetPath ().c_str ()), true );
264- }
265+ ConstString (build_path.GetPath ().c_str ()),
266+ ConstString (source_path.GetPath ().c_str ()),
267+ true );
265268 }
266- return true ;
267- });
268- }
269+ }
270+ return true ;
271+ });
272+ }
269273
270- // If we have a DBGBuildSourcePath + DBGSourcePath pair,
271- // append those to the source path remappings.
272-
273- plist.GetValueAsString (" DBGBuildSourcePath" ,
274- DBGBuildSourcePath);
275- plist.GetValueAsString (" DBGSourcePath" , DBGSourcePath);
276- if (!DBGBuildSourcePath.empty () &&
277- !DBGSourcePath.empty ()) {
278- if (DBGSourcePath[0 ] == ' ~' ) {
279- FileSpec resolved_source_path (DBGSourcePath.c_str ());
280- FileSystem::Instance ().Resolve (resolved_source_path);
281- DBGSourcePath = resolved_source_path.GetPath ();
282- }
283- module_sp->GetSourceMappingList ().Append (
284- ConstString (DBGBuildSourcePath),
285- ConstString (DBGSourcePath), true );
274+ // If we have a DBGBuildSourcePath + DBGSourcePath pair,
275+ // append those to the source path remappings.
276+
277+ plist.GetValueAsString (" DBGBuildSourcePath" ,
278+ DBGBuildSourcePath);
279+ plist.GetValueAsString (" DBGSourcePath" , DBGSourcePath);
280+ if (!DBGBuildSourcePath.empty () && !DBGSourcePath.empty ()) {
281+ if (DBGSourcePath[0 ] == ' ~' ) {
282+ FileSpec resolved_source_path (DBGSourcePath.c_str ());
283+ FileSystem::Instance ().Resolve (resolved_source_path);
284+ DBGSourcePath = resolved_source_path.GetPath ();
286285 }
286+ module_sp->GetSourceMappingList ().Append (
287+ ConstString (DBGBuildSourcePath),
288+ ConstString (DBGSourcePath), true );
287289 }
288290 }
289291 }
@@ -293,6 +295,11 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
293295 }
294296
295297 symbol_vendor->AddSymbolFileRepresentation (dsym_objfile_sp);
298+ if (repro::Generator *g =
299+ repro::Reproducer::Instance ().GetGenerator ()) {
300+ repro::FileProvider &fp = g->GetOrCreate <repro::FileProvider>();
301+ fp.recordInterestingDirectory (dsym_root);
302+ }
296303 return symbol_vendor;
297304 }
298305 }
0 commit comments