@@ -243,9 +243,9 @@ func (p *profileBuilder) convertLocationBack(ol *otelProfile.Location, dictionar
243243 return 0 , fmt .Errorf ("could not access mapping: %w" , err )
244244 }
245245
246- mappingId , err := p .convertMappingBack ( om , dictionary )
247- if err != nil {
248- return 0 , err
246+ mappingId , ok := p .mappingMap [ om ]
247+ if ! ok {
248+ return 0 , fmt . Errorf ( "mapping not found in mappingMap" )
249249 }
250250 gl := & googleProfile.Location {
251251 MappingId : mappingId ,
@@ -350,6 +350,30 @@ func (p *profileBuilder) convertSampleBack(os *otelProfile.Sample, dictionary *o
350350 return nil , fmt .Errorf ("invalid stack index: %d" , stackIndex )
351351 }
352352 stack := dictionary .StackTable [stackIndex ]
353+
354+ // First, gather map of locations pointing to each mapping
355+ locationMap := make (map [* otelProfile.Mapping ][]* otelProfile.Location )
356+
357+ for _ , locIdx := range stack .LocationIndices {
358+ loc , err := at (dictionary .LocationTable , locIdx )
359+ if err != nil {
360+ return nil , fmt .Errorf ("could not access location at index %d: %w" , locIdx , err )
361+ }
362+ mapping , err := at (dictionary .MappingTable , loc .GetMappingIndex ())
363+ if err != nil {
364+ return nil , fmt .Errorf ("could not access mapping at index %d: %w" , loc .GetMappingIndex (), err )
365+ }
366+ locationMap [mapping ] = append (locationMap [mapping ], loc )
367+ }
368+
369+ // Now, convert each mapping, based on information from all locations that point to it
370+ for mapping , locs := range locationMap {
371+ _ , err := p .convertMappingBack (locs , mapping , dictionary )
372+ if err != nil {
373+ return nil , err
374+ }
375+ }
376+
353377 for _ , olocIdx := range stack .LocationIndices {
354378 oloc , err := at (dictionary .LocationTable , olocIdx )
355379 if err != nil {
@@ -403,10 +427,33 @@ func (p *profileBuilder) convertSampleAttributesToLabelsBack(os *otelProfile.Sam
403427 return nil
404428}
405429
406- // convertMappingsBack converts a slice of OpenTelemetry Mapping entries to Google Mapping entries.
407- func (p * profileBuilder ) convertMappingBack (om * otelProfile.Mapping , dictionary * otelProfile.ProfilesDictionary ) (uint64 , error ) {
408- if i , ok := p .mappingMap [om ]; ok {
409- return i , nil
430+ // convertMappingBack converts an OpenTelemetry Mapping to a Google Mapping taking into account availability
431+ // of symbol data in all locations that point to this mapping.
432+ func (p * profileBuilder ) convertMappingBack (ols []* otelProfile.Location , om * otelProfile.Mapping , dictionary * otelProfile.ProfilesDictionary ) (uint64 , error ) {
433+ hasLines := true
434+ hasFunctions := true
435+ hasInlineFrames := true
436+ hasFilenames := true
437+
438+ /*
439+ We survey all locations that point to this mapping to determine
440+ whether the mapping has functions, filenames, line numbers, inline frames.
441+ Note that even if a single location does not have symbol information,
442+ the mapping is marked as not having that information.
443+ */
444+ for _ , ol := range ols {
445+ for i , line := range ol .Line {
446+ hasFunctions = hasFunctions && line .FunctionIndex > 0
447+ hasLines = hasLines && line .Line > 0
448+ hasInlineFrames = hasInlineFrames && i >= 1
449+
450+ if line .FunctionIndex > 0 {
451+ function , _ := at (dictionary .FunctionTable , line .FunctionIndex )
452+ if function != nil {
453+ hasFilenames = hasFilenames && function .FilenameStrindex > 0
454+ }
455+ }
456+ }
410457 }
411458
412459 buildID , _ := getAttributeValueByKeyOrEmpty (om .AttributeIndices , dictionary , "process.executable.build_id.gnu" )
@@ -420,10 +467,10 @@ func (p *profileBuilder) convertMappingBack(om *otelProfile.Mapping, dictionary
420467 FileOffset : om .FileOffset ,
421468 Filename : p .addstr (filenameLabel ),
422469 BuildId : p .addstr (buildID ),
423- HasFunctions : true ,
424- HasFilenames : true ,
425- HasLineNumbers : true ,
426- HasInlineFrames : true ,
470+ HasFunctions : hasFunctions ,
471+ HasFilenames : hasFilenames ,
472+ HasLineNumbers : hasLines ,
473+ HasInlineFrames : hasInlineFrames ,
427474 }
428475 p .dst .Mapping = append (p .dst .Mapping , gm )
429476 gm .Id = uint64 (len (p .dst .Mapping ))
0 commit comments