Saturday, 1 August 2026

Diagnosing Native Errors in .NET Apps Running in the Linux Containers (exit code 139) in AKS

 We might have to sometimes use native assembiles such Aspose.Slides.NET6.CrossPlatform as for specific needs.

 <PackageReference Include="Aspose.Slides.NET6.CrossPlatform" Version="26.9.0" />

However, when there is a native exception which is not propagating the exceptions to .NET app, but fails due to native errors and restart cotianers with exit code 139. 

Exit code 139 in a Linux container means the process was terminated due to a Segmentation Fault (SIGSEGV). The operating system killed the container because it attempted to access a memory location it wasn't allowed to touch. 

Linux calculates this exit code using the formula 128 + Signal Number. Because SIGSEGV is signal 11, the result is: (128+11=139)


But identifying root cause and debugging this sort of issue is not straigh forward. it is diffcult to locate which componet is giving the issue and restart container. From dotnet container logs, app insights etc., there will be no recorded exceptionas the error is not propagate to dotnet, and container restarts before that.

So what can we do to debug this sort of issue. The GNU debugger (GDB) is the right tool to use for this case.

First run the problomati pod and find its name. Then run below command to create a debugger.

kubectl debug -it <app-pod-name> -n <pod-name> \

  --image=ubuntu \

  --target=document-messageprocessor \

  --profile=general \

  -- bash


To setup gdb in the debug container we should run below command. It may prompt for region an city to find timezone. Provide corect values and proceed with the setup.

apt-get update && apt-get install -y gdb

Then we can run command to get dotnet program id (PID). Then start attching to the dotnet process.

ps aux | grep dotnet
gdb -p <dotnet pid>


In case if it jumps to (gdp) prompt without attaching properly.
Then run below commands to reattach.

detach

set sysroot /proc/1/root

attach 1



In case if it still stop similar to below issue we can run continue as command.


Then we can let the app actually run in to the real issue while gdb is attached. In my case it ws sending a message via Rabbit MQ to process a ppt file to generate preview.

Then we can start seeing SIG issues such as SIGABRT and SIGSEGV. Keep continue with continue command when you see SIGABRT. Then when we see SIGSEGV we can start running bt (backtrace) as command to see natve stack trace.


We can run below commands as well.
  • bt full stack trace plus the local variables for every stack frame
  • info threads show all threads
  • thread apply all bt show all threas native stack trace
Then you can provide this sort of native stack trace to an AI tool to analyze it and explain your problem which will identofy the cause as shown in below text.

Example AI output after analyzing the native stack trace.

  1. This showed the crashing thread hitting SIGSEGV, then CoreCLR's native fatal-error handler calling abort() → SIGABRT (exit code 139) — proving it was a native crash, not a managed .NET exception (which is also why nothing showed up in application logs).

  2. Found corrupted stack frames. Several consecutive stack slots near the top of the crashing thread's backtrace (frames #4–#14) contained garbage-looking 64-bit values instead of valid return addresses/pointers.

  3. Decoded the "garbage" as text. Pairing each 8-byte value's bytes LSB→MSB into 2-byte UTF-16LE code units, the corrupted stack spelled out:


"Noto Sans Armenian ExtraCondensed SemiBold"

  1. — a real, installed font family name (43 characters). That's the smoking gun: a long string had overwritten stack memory including return addresses, i.e. a stack buffer overflow, and it happened inside Aspose.Slides' native font-matching code path (only exercised by PPT-family formats, matching exactly which file types were crashing).

  2. Confirmed the trigger source. fonts-noto-extra was identified as the package supplying that overly long family name (and ~370 others up to 73 chars). Checksummed the actual crashing .ttf file 

Therefore, the decision was to remove the problematic font installation. After removed fonts-noto-extra, retested the same 6 previously-crashing files live via the gdb-attached pod — all passed.

No comments:

Popular Posts