# Exception behavior with errno

**URL:** https://forum.ada-lang.io/t/exception-behavior-with-errno/4658
**Category:** General
**Tags:** ada, gnat
**Created:** [August 23, 2026, 11:58am UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658 "2026-08-23T11:58:07Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![sbenitezb](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/sbenitezb/32/285_2.png) [@sbenitezb](https://forum.ada-lang.io/u/sbenitezb)
#### Post date: [August 23, 2026, 11:58am UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/1 "2026-08-23T11:58:07Z")

</div>

Hello. Does anybody know the GNAT behavior during exception raise or catch with respect to errno global variable? I assume that it might call some C function that might set it and trash previous C function errno state?

---

<div class="post-metadata">

### Author: ![liampwll](https://forum.ada-lang.io/letter_avatar_proxy/v4/letter/l/b19c9b/32.png) [@liampwll](https://forum.ada-lang.io/u/liampwll)
#### Post date: [August 23, 2026, 12:07pm UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/2 "2026-08-23T12:07:46Z")

</div>

Exceptions don’t do anything with errno. Why would you expect them to? Exceptions and errno are entirely unrelated concepts (from different languages no less).

---

<div class="post-metadata">

### Author: ![sbenitezb](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/sbenitezb/32/285_2.png) [@sbenitezb](https://forum.ada-lang.io/u/sbenitezb)
#### Post date: [August 23, 2026, 12:19pm UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/3 "2026-08-23T12:19:26Z")

</div>

GNAT might inject some C library call that could change it.

---

<div class="post-metadata">

### Author: ![liampwll](https://forum.ada-lang.io/letter_avatar_proxy/v4/letter/l/b19c9b/32.png) [@liampwll](https://forum.ada-lang.io/u/liampwll)
#### Post date: [August 23, 2026, 12:31pm UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/4 "2026-08-23T12:31:37Z")

</div>

It does use C because it uses GCC’s exception machinery, however I can’t imagine any possible implementation that would make use of errno. At most you’d hit it as a side effect if there’s a malloc somewhere in there that fails, though I’d expect a crash at that point anyway. If you’d like to trace through how it works then you probably want to start from System.Exceptions.Machine.

---

<div class="post-metadata">

### Author: ![OneWingedShark](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/onewingedshark/32/305_2.png) [@OneWingedShark](https://forum.ada-lang.io/u/OneWingedShark)
#### Post date: [August 23, 2026, 9:36pm UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/5 "2026-08-23T21:36:08Z")

</div>

> [@sbenitezb](#):
>
> Does anybody know the GNAT behavior during exception raise or catch with respect to errno global variable?

Since exceptions and error-nos are separate mechanisms, I would be surprised if there were _any_ non-explicit interactions.

> [@sbenitezb](#):
>
> I assume that it might call some C function that might set it and trash previous C function errno state?

Ah, well, there’s several simple ways to architect around this sort of thing, consider, for example:

```ada
-- Specification:
-- This calls C function IMPORTED, and CHECK_ERROR, and SET_ERROR.
Function Example( Object : Some_Record ) return Other_Record;

-- Implementation:
Function Example( Object : Some_Record ) return Other_Record is
  WHATEVER_ERROR : Constant Interfaces.C.Int := 3;
  NO_ERROR : Constant Interfaces.C.Int := 0;
  Procedure SET_ERROR( Value : Interfaces.C.Int )
    with Import, Convention => C, Link_Name => "SET_ERROR";
  Function CHECK_ERROR return Interfaces.C.Int
    with Import, Convention => C, Link_Name => "CHECK_ERROR";
  Procedure IMPORTED( Source : in Some_Record; Target : in out Other_Record )
    with Import, Convention => C, Link_Name => "IMPORTED";

Begin
  -- Call DO_CALL here, if using the "task-trick".
  Return Result : Aliased Other_Record do

    HANDLE_ERROR:
    declare
      Err : Interfaces.C.Int renames CHECK_ERROR;
    begin
      if Err = WHATEVER_ERROR then
        SET_ERROR( NO_ERROR );
        -- Call FINISH_CALL here, if using the Task-trick.
        Raise Appropriate_Exception;
      end if;
    end HANDLE_ERROR;
  End return;
End Example;

Task Task_Trick is
  Entry DO_CALL;
  Entry FINISH_CALL;
  Entry DONE;
End Task_Trick;

-- Implementation:
Task Task_Trick is
  Finished : Boolean := False;
Begin
  loop
    When Finished Exit;
    Select
      Accept Done; -- Set the Finished flag,
      Finished:= True;
    OR
      Accept DO_CALL; -- Lock calls,
      Accept FINISH_CALL; -- Free to accept another call.
    End Select;
  End loop;
End Task_Trick;

```

---

<div class="post-metadata">

### Author: ![charlie5](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/charlie5/32/626_2.png) [@charlie5](https://forum.ada-lang.io/u/charlie5)
#### Post date: [August 24, 2026, 3:09am UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/6 "2026-08-24T03:09:55Z")

</div>

FWIW, ‘gnat.OS\_Lib’ contains subprograms relating to ‘errno’ …

```ada
   function Errno return Integer;
   pragma Import (C, Errno, "__get_errno");
   -- Return the task-safe last error number

   function Errno_Message
     (Err : Integer := Errno;
      Default : String := "") return String;
   -- Return a message describing the given Errno value. If none is provided
   -- by the system, return Default if not empty, else return a generic
   -- message indicating the numeric errno value.

   procedure Set_Errno (Errno : Integer);
   pragma Import (C, Set_Errno, "__set_errno");
   -- Set the task-safe error number

```

I believe the Florist POSIX binding also handles ‘errno’.

---

<div class="post-metadata">

### Author: ![sbenitezb](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/sbenitezb/32/285_2.png) [@sbenitezb](https://forum.ada-lang.io/u/sbenitezb)
#### Post date: [August 24, 2026, 2:50pm UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/7 "2026-08-24T14:50:51Z")

</div>

Yes, I’m using GNAT.OS\_Lib to capture errno

---

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [August 24, 2026, 3:57pm UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/8 "2026-08-24T15:57:50Z")

</div>

Perhaps you can say how errno is related to exception propagation?

If you propagate an exception from bindings you must store errno or GetLastError as soon as possible before making any calls to any subprogram, e.g. before rendering the error code as text etc.

---

<div class="post-metadata">

### Author: ![sbenitezb](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/sbenitezb/32/285_2.png) [@sbenitezb](https://forum.ada-lang.io/u/sbenitezb)
#### Post date: [August 25, 2026, 10:07am UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/9 "2026-08-25T10:07:44Z")

</div>

I’m using a ZeroMQ binding that raises a single exception for any kind of C zeromq API call that returns error. I want to unwrap to proper Ada errors to raise and handle at the right place.

I could change the binding library to add the additional exceptions but I opted instead to catch that generic ZMQ\_Error, read the errno and raise the proper exception on my own code instead. Then of course I had that doubt that something in the Ada exception machinery could set errno to something else.

---

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [August 25, 2026, 10:41am UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/10 "2026-08-25T10:41:58Z")

</div>

> [@sbenitezb](#):
>
> I’m using a ZeroMQ binding that raises a single exception for any kind of C zeromq API call that returns error. I want to unwrap to proper Ada errors to raise and handle at the right place.

Maybe errno is likely lost at this point already. Does the library set errno instead of returning the code explicitly? If so it is an awful idea exactly because errno is extremely volatile, not meant for higher level protocols, not meant for tasking, non-portable even across UNIX clones and so on.

> [@sbenitezb](#):
>
> I could change the binding library to add the additional exceptions but I opted instead to catch that generic ZMQ\_Error, read the errno and raise the proper exception on my own code instead. Then of course I had that doubt that something in the Ada exception machinery could set errno to something else.

Why do not you just implement it in Ada? OK, some protocols are messed up beyond imaginable like AMQP.

(I considered implementing ZeroMQ at some point, but decided not to. I do not remember details).

Or, a better question, why do you use it at all? Is it so hard to serialize and send data over a socket?

---

<div class="post-metadata">

### Author: ![sbenitezb](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/sbenitezb/32/285_2.png) [@sbenitezb](https://forum.ada-lang.io/u/sbenitezb)
#### Post date: [August 25, 2026, 11:09am UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/11 "2026-08-25T11:09:52Z")

</div>

> Maybe errno is likely lost at this point already. Does the library set errno instead of returning the code explicitly? If so it is an awful idea exactly because errno is extremely volatile, not meant for higher level protocols, not meant for tasking, non-portable even across UNIX clones and so on.

The binding does not set errno, the C ZeroMQ library does on each function, and returns -1 to signal the error. The binding raises ZMQ\_Error regardless of the error kind, which makes difficult to handle the proper kind of error than if it raised different exceptions for different C errors.

> [@dmitry-kazakov](#):
>
> Why do not you just implement it in Ada? OK, some protocols are messed up beyond imaginable like AMQP.
> 
> (I considered implementing ZeroMQ at some point, but decided not to. I do not remember details).
> 
> Or, a better question, why do you use it at all? Is it so hard to serialize and send data over a socket?

I keep asking myself that question. I use ZeroMQ for IPC between an Ada backend and a GUI. I could use GNAT.Sockets, I guess, and reimplement all the ZeroMQ logic I need. ZeroMQ nicely wraps all the platform specific details and allows to select different transports for local or remote.

---

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [August 25, 2026, 11:31am UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/12 "2026-08-25T11:31:18Z")

</div>

> [@sbenitezb](#):
>
> The binding does not set errno, the C ZeroMQ library does on each function, and returns -1 to signal the error.

Then the bindings should do it this way:

```ada
if Result = -1 then
   declare
      Code : constant int := Errno;
   begin
      raise ZMQ_Error with ZMQ_Error_Text (Code) & " [" & Image (Code) & "]";
   end;
end if;

```

> [@sbenitezb](#):
>
> I keep asking myself that question. I use ZeroMQ for IPC between an Ada backend and a GUI

Why not using shared memory for IPC?

---

<div class="post-metadata">

### Author: ![charlie5](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/charlie5/32/626_2.png) [@charlie5](https://forum.ada-lang.io/u/charlie5)
#### Post date: [August 25, 2026, 11:52am UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/13 "2026-08-25T11:52:42Z")

</div>

If the GUI is in Ada, then perhaps ipDSA might be an option ? (It uses Dmitry’s shared memory 🙂).

---

<div class="post-metadata">

### Author: ![sbenitezb](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/sbenitezb/32/285_2.png) [@sbenitezb](https://forum.ada-lang.io/u/sbenitezb)
#### Post date: [August 25, 2026, 11:53am UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/14 "2026-08-25T11:53:10Z")

</div>

> [@dmitry-kazakov](#):
>
> Why not using shared memory for IPC?

That only works locally, which is fine for my current purposes, but it would prevent me from connecting a GUI to a remote machine if I ever wanted to do that. Of course, I could implement it as separate “transports”. Food for thought.

---

<div class="post-metadata">

### Author: ![sbenitezb](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/sbenitezb/32/285_2.png) [@sbenitezb](https://forum.ada-lang.io/u/sbenitezb)
#### Post date: [August 25, 2026, 11:55am UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/15 "2026-08-25T11:55:24Z")

</div>

I wish the GUI was in Ada, but it’s in C++/Qt6. When I considered implementing the IPC fully in Ada, it would have been a shared ibrary that C++ and Ada would consume to handle intercomms. But ZeroMQ looked like a ready to use alternative. The more I use it, the more I see some of the shortcomings and potential edge cases.

Just a side comment: I serialize all messages using ASN.1. Reason for this format is I like it as IDL and can be used from Ada and C. But I considered many alternatives.

---

<div class="post-metadata">

### Author: ![charlie5](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/charlie5/32/626_2.png) [@charlie5](https://forum.ada-lang.io/u/charlie5)
#### Post date: [August 25, 2026, 12:00pm UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/16 "2026-08-25T12:00:35Z")

</div>

> [@dmitry-kazakov](#):
>
> ```ada
> if Result = -1 then
> declare
> Code : constant int := Errno;
> begin
> raise ZMQ_Error with ZMQ_Error_Text (Code) & " [" & Image (Code) & "]";
> end;
> end if;
> 
> ```

Would it be better to use a ‘case’ statement on ‘Code’ and raise separate, appropriately named exceptions for each ‘Code’ value ?

---

<div class="post-metadata">

### Author: ![sbenitezb](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/sbenitezb/32/285_2.png) [@sbenitezb](https://forum.ada-lang.io/u/sbenitezb)
#### Post date: [August 25, 2026, 12:01pm UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/17 "2026-08-25T12:01:55Z")

</div>

I did consider doing that, and I do that on my own code. But since this is someone else’s library, I’m not sure they would like it.

---

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [August 25, 2026, 12:25pm UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/18 "2026-08-25T12:25:33Z")

</div>

> [@sbenitezb](#):
>
> Just a side comment: I serialize all messages using ASN.1. Reason for this format is I like it as IDL and can be used from Ada and C. But I considered many alternatives.

Interesting. I implemented full ASN.1, mainly for the sake LDAP and Cryptography. It was a torture. ITU-I, Videotext, ISO 646 such a joy!

---

<div class="post-metadata">

### Author: ![sbenitezb](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/sbenitezb/32/285_2.png) [@sbenitezb](https://forum.ada-lang.io/u/sbenitezb)
#### Post date: [August 25, 2026, 12:27pm UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/19 "2026-08-25T12:27:44Z")

</div>

I use this compiler [GitHub - esa/asn1scc: ASN1SCC: An open source ASN.1 compiler for embedded systems · GitHub](https://github.com/esa/asn1scc)

It compiles to Ada or C.

I saw on your Simple-Components that you had it, but I wanted code generation. I don’t remember if your implementation generates code or only de/serialize from Ada types.

---

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [August 25, 2026, 12:29pm UTC](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658/20 "2026-08-25T12:29:45Z")

</div>

> [@charlie5](#):
>
> Would it be better to use a ‘case’ statement on ‘Code’ and raise separate, appropriately named exceptions for each ‘Code’ value ?

Only if you have a limited and closed number of. To me it is usually a compromise. There are non-error codes like EAGAIN I do not like to be exceptions. There are errors I want to group together etc.

[Next page](https://forum.ada-lang.io/t/exception-behavior-with-errno/4658.md?page=2)
