symbolizer.go (go1.19.src) | : | symbolizer.go (go1.19.1.src) | ||
---|---|---|---|---|
skipping to change at line 208 | skipping to change at line 208 | |||
func Demangle(prof *profile.Profile, force bool, demanglerMode string) { | func Demangle(prof *profile.Profile, force bool, demanglerMode string) { | |||
if force { | if force { | |||
// Remove the current demangled names to force demangling | // Remove the current demangled names to force demangling | |||
for _, f := range prof.Function { | for _, f := range prof.Function { | |||
if f.Name != "" && f.SystemName != "" { | if f.Name != "" && f.SystemName != "" { | |||
f.Name = f.SystemName | f.Name = f.SystemName | |||
} | } | |||
} | } | |||
} | } | |||
var options []demangle.Option | options := demanglerModeToOptions(demanglerMode) | |||
for _, fn := range prof.Function { | ||||
demangleSingleFunction(fn, options) | ||||
} | ||||
} | ||||
func demanglerModeToOptions(demanglerMode string) []demangle.Option { | ||||
switch demanglerMode { | switch demanglerMode { | |||
case "": // demangled, simplified: no parameters, no templates, no return type | case "": // demangled, simplified: no parameters, no templates, no return type | |||
options = []demangle.Option{demangle.NoParams, demangle.NoTemplat eParams} | return []demangle.Option{demangle.NoParams, demangle.NoTemplatePa rams} | |||
case "templates": // demangled, simplified: no parameters, no return type | case "templates": // demangled, simplified: no parameters, no return type | |||
options = []demangle.Option{demangle.NoParams} | return []demangle.Option{demangle.NoParams} | |||
case "full": | case "full": | |||
options = []demangle.Option{demangle.NoClones} | return []demangle.Option{demangle.NoClones} | |||
case "none": // no demangling | case "none": // no demangling | |||
return | return []demangle.Option{} | |||
} | } | |||
panic(fmt.Sprintf("unknown demanglerMode %s", demanglerMode)) | ||||
} | ||||
func demangleSingleFunction(fn *profile.Function, options []demangle.Option) { | ||||
if fn.Name != "" && fn.SystemName != fn.Name { | ||||
return // Already demangled. | ||||
} | ||||
// Copy the options because they may be updated by the call. | // Copy the options because they may be updated by the call. | |||
o := make([]demangle.Option, len(options)) | o := make([]demangle.Option, len(options)) | |||
for _, fn := range prof.Function { | copy(o, options) | |||
if fn.Name != "" && fn.SystemName != fn.Name { | if demangled := demangle.Filter(fn.SystemName, o...); demangled != fn.Sys | |||
continue // Already demangled. | temName { | |||
} | fn.Name = demangled | |||
copy(o, options) | return | |||
if demangled := demangle.Filter(fn.SystemName, o...); demangled ! | } | |||
= fn.SystemName { | // Could not demangle. Apply heuristics in case the name is | |||
fn.Name = demangled | // already demangled. | |||
continue | name := fn.SystemName | |||
} | if looksLikeDemangledCPlusPlus(name) { | |||
// Could not demangle. Apply heuristics in case the name is | for _, o := range options { | |||
// already demangled. | switch o { | |||
name := fn.SystemName | case demangle.NoParams: | |||
if looksLikeDemangledCPlusPlus(name) { | ||||
if demanglerMode == "" || demanglerMode == "templates" { | ||||
name = removeMatching(name, '(', ')') | name = removeMatching(name, '(', ')') | |||
} | case demangle.NoTemplateParams: | |||
if demanglerMode == "" { | ||||
name = removeMatching(name, '<', '>') | name = removeMatching(name, '<', '>') | |||
} | } | |||
} | } | |||
fn.Name = name | ||||
} | } | |||
fn.Name = name | ||||
} | } | |||
// looksLikeDemangledCPlusPlus is a heuristic to decide if a name is | // looksLikeDemangledCPlusPlus is a heuristic to decide if a name is | |||
// the result of demangling C++. If so, further heuristics will be | // the result of demangling C++. If so, further heuristics will be | |||
// applied to simplify the name. | // applied to simplify the name. | |||
func looksLikeDemangledCPlusPlus(demangled string) bool { | func looksLikeDemangledCPlusPlus(demangled string) bool { | |||
if strings.Contains(demangled, ".<") { // Skip java names of the form "cl | // Skip java names of the form "class.<init>". | |||
ass.<init>" | if strings.Contains(demangled, ".<") { | |||
return false | ||||
} | ||||
// Skip Go names of the form "foo.(*Bar[...]).Method". | ||||
if strings.Contains(demangled, "]).") { | ||||
return false | return false | |||
} | } | |||
return strings.ContainsAny(demangled, "<>[]") || strings.Contains(demangl ed, "::") | return strings.ContainsAny(demangled, "<>[]") || strings.Contains(demangl ed, "::") | |||
} | } | |||
// removeMatching removes nested instances of start..end from name. | // removeMatching removes nested instances of start..end from name. | |||
func removeMatching(name string, start, end byte) string { | func removeMatching(name string, start, end byte) string { | |||
s := string(start) + string(end) | s := string(start) + string(end) | |||
var nesting, first, current int | var nesting, first, current int | |||
for index := strings.IndexAny(name[current:], s); index != -1; index = st rings.IndexAny(name[current:], s) { | for index := strings.IndexAny(name[current:], s); index != -1; index = st rings.IndexAny(name[current:], s) { | |||
End of changes. 11 change blocks. | ||||
25 lines changed or deleted | 39 lines changed or added |