C

Toward _FORTIFY_SOURCE parity between Clang and GCC

Toward _FORTIFY_SOURCE parity between Clang and GCC

GCC combined with glibc can detect instances of buffer overflow by standard C library functions. When a user passes the -D_FORTIFY_SOURCE={1,2} preprocessor flag and an optimization level greater or equal to -O1, an alternate, fortified implementation of the function is used when calling, say, strcpy. Depending on the function and its inputs, this behavior may result in a compile-time error, or a runtime error triggered upon execution. (For more info on this feature, there’s an excellent blog post here on the subject).

Continue reading Toward _FORTIFY_SOURCE parity between Clang and GCC

Share
MIR: A lightweight JIT compiler project

MIR: A lightweight JIT compiler project

For the past three years, I’ve been participating in adding just-in-time compilation (JIT) to CRuby. Now, CRuby has the method-based just-in-time compiler (MJIT), which improves performance for non-input/output-bound programs.

The most popular approach to implementing a JIT is to use LLVM or GCC JIT interfaces, like ORC or LibGCCJIT. GCC and LLVM developers spend huge effort to implement the optimizations reliably, effectively, and to work on a lot of targets. Using LLVM or GCC to implement JIT, we can just utilize these optimizations for free. Using the existing compilers was the only way to get JIT for CRuby in the short time before the Ruby 3.0 release, which has the goal of improving CRuby performance by three times.

So, CRuby MJIT utilizes GCC or LLVM, but what is unique about this JIT?

Continue reading “MIR: A lightweight JIT compiler project”

Share
Deploying debuginfod servers for your developers

Deploying debuginfod servers for your developers

In an earlier article, Aaron Merey introduced the new elfutils debuginfo-server daemon. With this software now integrated and released into elfutils 0.178 and coming to distros near you, it’s time to consider why and how to set up such a service for yourself and your team.

Recall that debuginfod exists to distribute ELF or DWARF debugging information, plus associated source code, for a collection of binaries. If you need to run a debugger like gdb, a trace or probe tool like perf or systemtap, binary analysis tools like binutils or pahole, or binary rewriting libraries like dyninst, you will eventually need debuginfo that matches your binaries. The debuginfod client support in these tools enables a fast, transparent way of fetching this data on the fly, without ever having to stop, change to root, run all of the right yum debuginfo-install commands, and try again. Debuginfo lets you debug anywhere, anytime.

We hope this opening addresses the “why.” Now, onto the “how.”

Continue reading “Deploying debuginfod servers for your developers”

Share
Report from July 2019 ISO C++ Standards Committee Meeting (Concurrency and Parallelism Study Group)

Report from July 2019 ISO C++ Standards Committee Meeting (Concurrency and Parallelism Study Group)

The summer 2019 WG21 C++ Committee meeting was held in Cologne, Germany during the week of July 13. As usual,
Red Hat sent three representatives, Jason Merrill in the Core Working Group (CWG), Jonathan Wakely in the Library Working Group (LWG), and myself in the Concurrency and Parallelism Study Group (SG1). This rather late report covers the Cologne SG1 session and looks ahead to some revised papers from that meeting, which are scheduled for the fall meeting in Belfast, Northern Ireland, for the first week of November 2019.

Continue reading “Report from July 2019 ISO C++ Standards Committee Meeting (Concurrency and Parallelism Study Group)”

Share
How to debug where a function returns using LLDB from the command line

How to debug where a function returns using LLDB from the command line

I often find myself in a situation when I want to know where a function returns. There’s no need to know the return value, as this may be the same for multiple code paths (e.g., nullptr if something went wrong). It is embarrassing, but I sometimes have put fprintf(stderr, "T1"); in my code just to follow which path the execution took. Needless to say, this behavior requires manual editing and recompilation and should be avoided if possible.

Here’s a way to elegantly debug where a function returns using lldb from the command line.

Continue reading “How to debug where a function returns using LLDB from the command line”

Share
Efficient string copying and concatenation in C

Efficient string copying and concatenation in C

Among the most heavily used string handling functions declared in the standard C <string.h> header are those that copy and concatenate strings. Both sets of functions copy characters from one object to another, and both return their first argument: a pointer to the beginning of the destination object. The choice of the return value is a source of inefficiency that is the subject of this article.

The code examples shown in this article are for illustration only. They should not be viewed as recommended practice and may contain subtle bugs.

Continue reading “Efficient string copying and concatenation in C”

Share
How C array sizes become part of the binary interface of a library

How C array sizes become part of the binary interface of a library

Most C compilers allow accessing an array declared extern, which has indeterminate bounds, like this:

extern int external_array[];

int
array_get (long int index)
{
  return external_array[index];
}

The definition of external_array could reside in a different translation unit and look like this:

int external_array[3] = { 1, 2, 3 };

The question is what happens if this separate definition is changed to this:

int external_array[4] = { 1, 2, 3, 4 };

Or this:

int external_array[2] = { 1, 2 };

Does either change preserve the binary interface (assuming that there is a mechanism that allows the application to determine the size of the array at run time)?

Curiously, the answer is that on many architectures, increasing the array size breaks binary interface (ABI) compatibility. Decreasing the array size may also cause compatibility problems. We’ll look more closely at ABI compatibility in this article and explain how to avoid problems.

Continue reading “How C array sizes become part of the binary interface of a library”

Share
A platform interface for the GNU C Library

A platform interface for the GNU C Library

Application developers continue to need newer versions of libraries, including core runtimes like GNU C Library (glibc), for their applications. In this article, I’ll look at some issues related to upgrading glibc in an operating system (OS) distribution, and I also encourage you to read Florian Weimer’s excellent blog post on the topic.

The problem

Deciding between a library rebase or continued backporting of commits involves a complex set of risks and rewards. For some customers and users, it is important not to rebase the library (ensuring the lowest risk of impact by change); but for others, the rebase brings valuable bug fixes (lowest risk of impact from known issues). In other cases, the newer library may perform better, even if the interfaces haven’t changed, because it can take advantage of newer hardware or a newer Linux kernel (performance advantage to first mover).

There is no way to simultaneously satisfy all the requirements of slow-moving versus fast-moving development. The recent work in Fedora Modularity is aimed at solving the root of this problem, but there is a limit to this work. The further down the stack you go, the harder the problem becomes. The potential for breakage further up the stack increases. You can’t always arbitrarily change a component’s installed version without consequences, either at build time or at runtime.

Continue reading “A platform interface for the GNU C Library”

Share
Using .NET PInvoke for Linux system functions

Using .NET PInvoke for Linux system functions

If you’ve developed Windows applications with .NET, you may have found yourself in a situation where the framework did not provide the APIs you needed. When that happens, you first need to identify the system APIs and then make them available using PInvoke. A website like pinvoke.net provides copy-and-pasteable code snippets for many Win32 API functions.

.NET Platform Invoke (PInvoke) makes it easy to consume native libraries. In this article, we’ll take a look at using PInvoke for Linux system functions.

Continue reading “Using .NET PInvoke for Linux system functions”

Share