News for hackers. Stuff that matters.

JacobCarlborg

Re:Bringing Record and Replay debugging everywhere on Linux on Wednesday April 02, 2025 @03:17AM (#43554377)
Here's a talk on that topic: https://infocondb.org/con/recon/recon-2023/be-kind-please-re.... IIRC, they ended up implementing a form of lightweight VM to be able to instrument programs on macOS.
Had a quick look. Seems like an interesting tool. I know there are many companies in Europe that, for regulations and compliance reasons, cannot have their data leave Europe. As far as I can see from the documentation, the data is stored in the US. Would be nice to have an option to store the data in Europe. Or not having to upload any data at all. But instead have the option export an artifact that can be processed later. But perhaps that defeats the business.
Re:Show HN: Cross-Platform GitHub Action on Tuesday January 17, 2023 @01:58AM (#34409821)
And you can run tests, not just compile.
Re:Show HN: Cross-Platform GitHub Action on Tuesday January 17, 2023 @01:57AM (#34409818)
Yeah, I've been using `docker/setup-qemu-action` as well to run on non-x86-64 architectures for Linux [1]. But since it's Docker it's Linux only and doesn't support other operating systems.

GitHub has Apple Silicon on the roadmap, but IIRC it was at the end of this year. They already support Apple Silicon for self hosted runners [2].

[1] https://github.com/jacob-carlborg/lime/blob/f4d9c8c4265b61b2...

[2] https://github.blog/changelog/2022-08-09-github-actions-self...

Re:Show HN: Cross-Platform GitHub Action on Monday January 16, 2023 @02:30PM (#34404538)
I've created a GitHub Action for running commands on multiple platforms. This includes platforms that GitHub Actions don't natively support. It currently supports FreeBSD, OpenBSD and NetBSD. OpenBSD can run on x86-64 and ARM64, the other operating systems run on x86-64.

Some of the features that are supported include:

* Multiple operating system with one single action

* Multiple versions of each operating system

* Allows to use default shell or Bash shell

* Low boot overhead

* Fast execution

* Runs on both macOS and Linux runners

Compared to similar solutions like https://github.com/vmactions/freebsd-vm, the boot time is around a fifth and the full execution time for the same job is around half of freebsd-vm (last time I tried).

The readme contains more information about how it all works under the hood.

Re:Amazon EC2 M1 Mac Instances on Thursday December 02, 2021 @02:24PM (#29421137)
You can use this GitHub action [1] to get SSH access to a GitHub runner. If you need access to the GUI you should be able to use ngrok, perhaps with this GitHub action [2]. I've tried tmate both with Linux and macOS runners. I've only tried ngrok with Linux runners.

CircleCI supports macOS runners and has native support for rerunning failed builds with SSH access. So just setup a job that always fails.

[1] https://github.com/marketplace/actions/debugging-with-tmate [2] https://github.com/marketplace/actions/ngrok-tunnel

This seems perfect to combine with αcτµαlly pδrταblε εxεcµταblε and cosmopolitan libc [1].

[1] https://justine.lol/cosmopolitan/index.html

Re:Reducing Rust Incremental Compilation Times on macOS on Sunday April 18, 2021 @08:21AM (#26851811)
The system linker strips debug info from the executable. The way the debugger finds debug info is that the debug info is available in the object files. A reference to the object files is added to the executable. The debugger can find the object files and read the debug info from the object files. I have no experience with Rust but in opinion this should be the default behavior for debug builds, no need to generate a dSYM file. The dSYM file is used if you want to ship debug info with your final release build to customers. There's no need for dSYM during regular development workflows.

It's possible to get the linker to keep the debug info by tweaking the section attributes. By default all debug info related sections have the `S_ATTR_DEBUG` flag. If that is replaced with the `S_REGULAR` flag the linker will keep those sections. The DMD D compiler does this for the `__debug_line` section [1][2][3]. This allows for uncaught exceptions to print a stack trace with filenames and line numbers. Of course, DMD uses a custom backend so this change was easy. Rust which relies on LLVM would probably need a fork.

[1] https://github.com/dlang/dmd/pull/8168 [2] https://github.com/dlang/dmd/blob/33406c205b76a8c2b5fb918da1... [3] https://github.com/dlang/dmd/blob/33406c205b76a8c2b5fb918da1...

If you want crazy fast build times, then D is your best bet [1]. D's compile times are faster than most other languages (I'm not counting Vox, it's too experimental).

[1] https://github.com/nordlow/compiler-benchmark

This is very common in D and D doesn't not have any macro system. It uses regular syntax (more or less). D was doing this way before Zig existed and before C++ had constexpr. Simple example of platform specific members:

  struct Socket
  {
      version (Posix)
          int handle;
      else version (Windows)
          SOCKET handle;
      else
          static assert(false, "Unsupported platform");
  }
Another example is the checked numeric type [1] in the D standard library. It takes two types as parameters. The first being the underlying type and the second being a "hook" type. The hook type allows the user to decide what should happen in various error conditions, like overflow, divide by zero and so on. The implementation is written in a Design By Introspection style and inspects the hook type and adopts its implementation depending on what hooks it provides. If the hook type implements the hook for overflow, that hook will be executed, otherwise it falls back to some default behavior.

[1] https://dlang.org/phobos/std_experimental_checkedint.html

In D, all semantic analysis is performed eagerly (I think), except for templates. D also supports CTFE (Compile Time Function Evaluation), `static if`, `static assert` and a few other language constructs that are evaluated at compile time.

I experimented a bit at how D's documentation generator behaves using these language constructs. Here's a snippet of some D code:

  /// some struct description
  struct Foo(T) // template
  {
      /// some alias description
      alias Result = int;
  
      /// some method description
      Result foo()
      {
          string a = 3; // this does not normally compile
      }
  
      static if (is(T == int)) // evaluated at compile time
      {
          /// some method description 2
          void bar() {}
      }
  
      version (Windows)
      {
          /// some method description for Windows
          void bazWindows() {}
      }
  
      else version (Posix)
      {
          /// some method description for Posix
          void bazPosix() {}
      }
  
      else
          static assert(false, "Unsupported platform"); // evaluated at compile time
  }
When generating documentation for the above code, and `Foo` has not been instantiated, the generated docs will include `Foo`, `Result`, `foo`, `bar`, and `bazWindows`. This is regardless of platform. The return type of `foo` will be `Result` and not `int`. This clearly shows that the D compiler doesn't perform semantic analysis when generating documentation. When doing a regular compilation and `Foo` is instantiated, `bar` will only be included if `T` is an `int`. `bazWindows` will only be compiled on Windows and `bazPosix` will only be compiled on Posix platforms.

Looking at the implementation, the compiler will generate the docs after semantic analysis and only if there are no errors. But, if `Foo` is never instantiated no errors have occurred so it will continue to generate the docs.

On the other hand, if `Foo` is instantiated (and compiles) the compiler will generate docs for the AST after semantic analysis has been performed and `bazWindows` will only be included if the docs were generated on Windows and `bazPosix` will only be included on Posix platforms. What's weird though, is that it seems `bar` will be included regardless of what type `T` is.

Re:Native Mac APIs for Go on Thursday February 04, 2021 @12:58PM (#26027931)
D has native support for calling Objective-C. No need to integrate with the Objective-C runtime directly. Everything is written using familiar D syntax. No extra overhead compared to Objective-C. The generated D code is the same as the Objective-C compiler would generate.

https://dlang.org/spec/objc_interface.html

Re:Objective-Rust on Sunday August 30, 2020 @05:18AM (#24322317)
D has had native interoperability support for Objective-C for a couple of years now: https://dlang.org/spec/objc_interface.html.