在 Linux 上使用 Avalonia 和 CefGlue:崩溃分析
介绍
本文主要记录了在 Avalonia 中使用 CefGlue(基于 .NET 的 Chrome 嵌入内核的封装库)时遇到的问题,目的是测试 Avalonia 的 Chrome 内核在 Linux 系统中的兼容性。然而在实际运行时,我们意外地遇到了运行崩溃的问题。
环境
测试环境如下:
- Ubuntu 24.04 桌面环境:GNOME
- KUbuntu 24.04 桌面环境:KDE
- Avalonia 版本:11.0.4 ~ 11.2.2
测试示例
测试用例来源于 CefGlue GitHub 仓库 中的 Demo.Avalonia 示例项目。
测试结果
-
Ubuntu 22.10
无法运行,提示不兼容并要求更高版本的依赖。 -
Ubuntu 24.04
同样无法运行,出现运行时崩溃。 -
KUbuntu 24.04
运行正常。
问题原因
问题发生在加载 CefBrowser 时。调试表明这是由于未正确初始化字体的 Face,导致文本整形过程中出现崩溃。
解决方案(临时修复)
如果在运行时遇到以下 Segment Fault 错误,可以通过提前初始化一次文本整形来规避问题。
修复代码
在应用的启动代码中添加以下方法:
public partial class App : Application
{
public override void OnFrameworkInitializationCompleted()
{
Preinitialize_ShapeText(); // 提前初始化字体的 ShapeText
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
// 应用生命周期初始化代码
}
base.OnFrameworkInitializationCompleted();
}
private static void Preinitialize_ShapeText()
{
var text = "FixedShapeTextCrashBug\t";
var options = new TextShaperOptions(
Typeface.Default.GlyphTypeface,
12, 0,
CultureInfo.CurrentCulture,
100);
var shapedBuffer = TextShaper.Current.ShapeText(
text.AsMemory().Slice(6), options);
}
}
错误详情
运行时的异常结果如下:
Thread 1 "Xilium.CefGlue." received signal SIGSEGV, Segmentation fault.
0x0000555555dadea0 in ?? ()
(gdb) bt
#0 0x0000555555dadea0 in ?? ()
#1 0x00007fff746f8aab in hb_face_t::reference_table (tag=<optimized out>, this=<optimized out>)
at ../src/hb-face.hh:79
...
问题发生在 Harfbuzz 的 hb_face_t::reference_table 函数调用过程中,具体分析详见下文。
分析过程
初步排查
-
检查 Harfbuzz 库版本
怀疑 Harfbuzz 库版本不匹配,但 Ubuntu 和 Kubuntu 系统中使用的是相同版本。 -
升级 Avalonia
将 Avalonia 从 11.0.4 升级至 11.2.2,但问题依旧。 -
检查 Avalonia 的 Skia 更新
Avalonia 的 GitHub 仓库最近更新了 Skia 和 Harfbuzz 到版本 8.3.3。尝试升级 Avalonia 到 Nightly 版本,问题依然存在。
调试堆栈
托管堆栈的错误信息:
(lldb) clrstack
OS Thread Id: 0x84ef (1)
Child SP IP Call Site
00007FFFFFFF60D8 0000555556a9a410 [InlinedCallFrame: 00007fffffff60d8] HarfBuzzSharp.HarfBuzzApi.hb_shape_full(IntPtr, IntPtr, HarfBuzzSharp.Feature*, UInt32, Void**)
00007FFFFFFF60D8 00007fff7aea7023 [InlinedCallFrame: 00007fffffff60d8] HarfBuzzSharp.HarfBuzzApi.hb_shape_full(IntPtr, IntPtr, HarfBuzzSharp.Feature*, UInt32, Void**)
00007FFFFFFF60D0 00007FFF7AEA7023 ILStubClass.IL_STUB_PInvoke(IntPtr, IntPtr, HarfBuzzSharp.Feature*, UInt32, Void**)
00007FFFFFFF6160 00007FFF7AEA6BE6 HarfBuzzSharp.Font.Shape(HarfBuzzSharp.Buffer, System.Collections.Generic.IReadOnlyList`1<HarfBuzzSharp.Feature>, System.Collections.Generic.IReadOnlyList`1<System.String>)
00007FFFFFFF6310 00007FFF7AEA657A HarfBuzzSharp.Font.Shape(HarfBuzzSharp.Buffer, HarfBuzzSharp.Feature[])
00007FFFFFFF6340 00007FFF7AEA44C4 Avalonia.Skia.TextShaperImpl.ShapeText(System.ReadOnlyMemory`1<Char>, Avalonia.Media.TextFormatting.TextShaperOptions) [E:\Exploit\AvaloniaUI\Avalonia\src\Skia\Avalonia.Skia\TextShaperImpl.cs @ 46]
00007FFFFFFF66B0 00007FFF7AEA3F8B Avalonia.Media.TextFormatting.TextShaper.ShapeText(System.ReadOnlyMemory`1<Char>, Avalonia.Media.TextFormatting.TextShaperOptions) [E:\Exploit\AvaloniaUI\Avalonia\src\Avalonia.Base\Media\TextFormatting\TextShaper.cs @ 45]
00007FFFFFFF6720 00007FFF7AEA3D6D Avalonia.Media.TextFormatting.TextFormatterImpl.ShapeTogether(System.Collections.Generic.IReadOnlyList`1<Avalonia.Media.TextFormatting.UnshapedTextRun>, System.ReadOnlyMemory`1<Char>, Avalonia.Media.TextFormatting.TextShaperOptions, Avalonia.Media.TextFormatting.TextShaper, RentedList`1<Avalonia.Media.TextFormatting.TextRun>) [E:\Exploit\AvaloniaUI\Avalonia\src\Avalonia.Base\Media\TextFormatting\TextFormatterImpl.cs @ 372]
00007FFFFFFF6820 00007FFF7AE9599E Avalonia.Media.TextFormatting.TextFormatterImpl.ShapeTextRuns(System.Collections.Generic.IReadOnlyList`1<Avalonia.Media.TextFormatting.TextRun>, Avalonia.Media.TextFormatting.TextParagraphProperties, Avalonia.Media.TextFormatting.FormattingObjectPool, Avalonia


801

被折叠的 条评论
为什么被折叠?



