Re: request for help: LLM-based quality assurance

Tim Rühsen <[email protected]>
Newsgroups gmane.comp.lib.gnulib.bugs
Message-ID <[email protected]>
 From my experiment with a local LLM.

Starting server in one console:
$ llama.cpp/build/bin/llama-server -m 
~/.cache/huggingface/hub/models--unsloth--Qwen3.6-35B-A3B-GGUF/snapshots/9280dd353ab587157920d5bd391ada414d84e552/Qwen3.6-35B-A3B-UD-IQ2_M.gguf 
--n-gpu-layers 99 --temp 0.6 --top-p 0.95 --top-k 20 --min-p 0.00 
--cache-type-v q4_0 --cache-type-k q4_0 --presence-penalty 1.0
0.00.131.117 I log_info: verbosity = 3 (adjust with the `-lv N` CLI arg)
0.00.131.120 I device_info:
0.00.131.204 I   - Vulkan0 : AMD Radeon Graphics (RADV PHOENIX) (24266 
MiB, 22698 MiB free)
0.00.131.214 I   - CPU     : AMD Ryzen 7 8845HS w/ Radeon 780M Graphics 
(15765 MiB, 15765 MiB free)
0.00.131.238 I system_info: n_threads = 8 (n_threads_batch = 8) / 16 | 
CPU : SSE3 = 1 | SSSE3 = 1 | AVX = 1 | AVX2 = 1 | F16C = 1 | FMA = 1 | 
BMI2 = 1 | AVX512 = 1 | AVX512_VBMI = 1 | AVX512_VNNI = 1 | AVX512_BF16 
= 1 | LLAMAFILE = 1 | OPENMP = 1 | REPACK = 1 |
,,,


Running the `pi` agent with
(i="17dc60e624cd6fc3491f9cb002f760d60e66ce8b"; pi "Review commit $i, use 
the code-reviewer skill. Think deeply about all implications for the 
various platforms that gnulib targets. Gnulib is a portability wrapper. 
Write the review result into '$i.txt'" -p)

$ cat 17dc60e624cd6fc3491f9cb002f760d60e66ce8b.txt
###########
## Review Summary

This commit correctly fixes a platform-specific bug where uClibc-ng was 
incorrectly treated as glibc for the UTF-8 locale optimization path. The 
fix adds `!__UCLIBC__` to all conditions gating UTF-8-specific 
optimizations on `__GLIBC__ >= 2`. This is a critical correctness fix 
for embedded Linux systems using uClibc-ng.

## Critical

**lib/mbrtoc32.c and lib/mbrtowc.c — UTF-8 optimization path was 
incorrectly enabled for uClibc-ng**

Before this fix, the conditions `(GNULIB_WCHAR_SINGLE_LOCALE && 
__GLIBC__ >= 2)` would be true on uClibc-ng, because uClibc-ng defines 
`__GLIBC__`. However, uClibc-ng's internal `mbstate_t` representation 
differs from glibc's. The optimization code relies on knowing the exact 
layout of `mbstate_t` internals (e.g., `__count` field structure with 
specific bit layouts for input byte counting), which is glibc-specific.

On uClibc-ng, this would cause:
- Incorrect state tracking during multi-byte character processing
- Potential memory corruption or misaligned reads from 
`mbstate_t.__count` and related fields
- Silent incorrect return values or EILSEQ errors on valid UTF-8 input

The fix correctly excludes uClibc-ng from this optimization path, 
causing it to fall back to the generic path which works with any 
`mbstate_t` implementation.

## Suggestions

**lib/mbrtowc.c:114 — NULL-handling condition still uses `__GLIBC__ >= 
2` without `!__UCLIBC__`**

The NULL-handling workaround at line 114 (the `if (s == NULL)` block) 
still uses `(GNULIB_WCHAR_SINGLE_LOCALE && __GLIBC__ >= 2)` without 
excluding uClibc-ng. While this is a different concern than the UTF-8 
optimization (it's about detecting whether the system has a bug where it 
doesn't return `(size_t) -2` for empty input), it means uClibc-ng will 
still use the glibc-specific NULL-handling path.

This is not incorrect per se — the NULL-handling logic is more generic 
than the UTF-8 optimization — but it would be more consistent to also 
exclude uClibc-ng here, or explicitly document why uClibc-ng is 
intentionally included for this specific condition. If uClibc-ng does 
have the same empty-input bug as glibc, then it's fine; if not, this is 
unnecessary code.

```c
/* Before (line 114) */
# if (MBRTOWC_RETVAL_BUG || MBRTOWC_EMPTY_INPUT_BUG || 
MBRTOWC_INVALID_UTF8_BUG \
       || (GNULIB_WCHAR_SINGLE_LOCALE && __GLIBC__ >= 2))

/* Suggested: consider whether uClibc-ng needs this path */
# if (MBRTOWC_RETVAL_BUG || MBRTOWC_EMPTY_INPUT_BUG || 
MBRTOWC_INVALID_UTF8_BUG \
       || (GNULIB_WCHAR_SINGLE_LOCALE && __GLIBC__ >= 2 && !__UCLIBC__))
```

## Nitpicks

**Commit message typo** — "optimze" should be "optimize". Minor, but the 
commit message has a typo: `mbrtoc32, mbrtowc: do not optimze for 
uClibc-ng`.

**ChangeLog attribution** — The ChangeLog entry credits Waldemar 
Brodkorb as the reporter and Paul Eggert as the committer. This is 
correct GNU style. However, the ChangeLog header uses the format 
`YYYY-MM-DD  Author Name  <email>` with two spaces between date and 
name, while the body uses tab indentation. This is consistent with 
existing GNU coding conventions, so no issue here.

## What looks good

The fix is surgical and targeted — it only changes the specific 
conditions that gate UTF-8-specific optimizations on `__GLIBC__ >= 2`, 
adding `!__UCLIBC__` without touching any other logic. This minimizes 
the risk of introducing regressions. The pattern `&& !__UCLIBC__` is 
already well-established throughout gnulib (visible in 
`lib/wprintf-parse.h`, `lib/printf-parse.h`, `lib/string.in.h`, 
`lib/wchar.in.h`, etc.), so this commit follows existing conventions.

## Platform implications

- **uClibc-ng (ARM, MIPS, RISC-V embedded)**: This is the primary 
beneficiary. Embedded systems using uClibc-ng will now correctly fall 
through to the generic multibyte conversion path instead of using 
glibc-specific internal state assumptions.
- **glibc (Linux desktop/server)**: No change in behavior — the 
`!__UCLIBC__` condition is already implicitly true on glibc since 
`__UCLIBC__` is not defined.
- **musl**: No change — musl doesn't define `__GLIBC__` at all, so these 
conditions are false regardless.
- **BSD systems (FreeBSD, NetBSD, OpenBSD)**: No change — these don't 
define `__GLIBC__`.
- **Windows/MinGW**: No change — these don't define `__GLIBC__`.
- **Solaris, HP-UX, AIX**: No change — these don't define `__GLIBC__`.

The fix is narrowly scoped to the UTF-8 optimization path and has no 
negative impact on any other platform.
###########


Local models are of course not as powerful as commercial high-end 
models. But maybe good enough, at least better than nothing and 
low-cost. Caveat: Running the same model on CPU (8 cores / 16 threads) 
is ~10x slower.
Gitlab hosted runners: 
https://docs.gitlab.com/ci/runners/hosted_runners/linux/
For Gitlab CI I successfully use saas-linux-xlarge-amd64 for slow 
cross-builds and valgrind testing (for wget2 CI).

The agent took ~2-3 Minutes to finish. On my machine, the token 
processing speed is ~200t/s for input tokens and ~25t/s for output tokens.

The review density highly depends on the prompting (skills are just 
prompts + some little meta info). Scripts can be added, the output 
analyzed by LLM. So any extensions possible.

Btw (if you wonder), the `code-reviewer` skill is a very generic/random 
review skill, mostly optimized for web/Javascript. Not even worth 
copying it here. We should craft a very specific one for gnulib, with 
all the rules we like to be checked.

Regards, Tim
OpenPGP_signature.asc (application/pgp-signature, 840 B)
-----BEGIN PGP SIGNATURE-----

wsF5BAABCAAjFiEEHLJ9vJhhSy1YQWRtCDAttqJnBCgFAmokTKAFAwAAAAAACgkQCDAttqJnBCi0
5Q/+JGfpjjMJhjd8FH8UAWpk2s+J5I+hfzUJS7dhQbVhm46HDUurr+CUSQVhaskw8sKJZnXy2ZeZ
tfQry3ueYnjZEYPUkC+WVg0VPnQW0viW/LCZgqpUH0Yf9zDoF8e3i89ZbqBZArPacc1I1Q84prmK
vYZfuJIOXeEMIg2LgSrM7nXP5oYbUWuP0obOZkme94R5XRYDJDmC78WxCwi//kGgdhfYT9X2zKxD
HJGowVvW94Law8KWNrWw0YK7SxaCcXMT9stE0xkQ391d/dM1FmEw2FI3+VC/MXcp0SjIxSkHE/Qz
gsiF3L/nCOA0wXq2kphMmkEB1UW6v7sQLsbuAM/FqzqKcdnlhcCQLm90yw5x1bIxy2K7jTwlCxnP
MXxLhnoDv1cY3zunnRXYg6QYyDTTm0G5WfwYyZsHjcMTAwCQE4zbZIcW1d/cMfu27SiRh/xiubA+
TcL5VTMbhNFVNUz+FqAIMEuvLR3vVzi47kznTFyrTgFSmx6Q0fxj2lHzs47ZK4imHaefNzAFnrn1
BwjLZlH7yfrNigafK/PKY8vgbAnXFu+DNpJ84LHMPbu4hhGzcNpXiCHXAy2qSFlP/PeM7WBrjkQz
nUwl8LflUrUyimXU7O0CiypaqNRVBnYhl4F2KerUmWmFGl/1nITH8Q550oaMd0zfiGJIKQLhavm9
jLA=
=mQ8q
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.