[m-users.] Crash in improved ODBC library when compiled in hlc.par.gc grade
Volker Wysk
post at volker-wysk.de
Wed Oct 21 23:36:06 AEDT 2026
Am Montag, dem 19.10.2026 um 19:52 +0200 schrieb Fabrice Nicol:
> Hi Volker,
> I have not reproduced the failure, nor did I closely inspect the relevant
> code. This said, I met somewhat comparable issues 3 years ago in work that
> I unfortunately cannot open source.
> To boil down the lessons I drew to the bare essentials: success in one
> grade does not establish that the C interface is correct.
I assume, with "C interface" you mean the C parts of the ODBC library.
> Plausible causes include an invalid ODBC buffer length or lifetime, an
> out-of-bounds write, a Mercury pointer retained in storage not visible to
> GC (see 4-5. below), incorrect heap-state handling across C/Mercury
> boundaries or, more probably, concerning parallel runs, a race involving
> shared handles or buffers.
> And the above does not preclude the possibility of a compiler/runtime
> problem.
> I would perhaps try the following:
> 1. Make a small standalone reproducer with fixed database contents, query
> and ordering. Include a worker count. Cleanly rebuild all Mercury
> components for each grade. Compare hlc.par.gc with hlc.gc where supported,
> and vary worker count separately; repeat the original asm_fast comparison
> with the same compiler.
I've already made a small reproducer, see my original mail. Or do you mean
something different? And what do you mean by "worker"? (This isn't related
to my Mfwpar library, where we have workers).
I've built and run the test program (reproducer) in the hlc.gc grade. It
runs and exhibits what looks very much like the same segmentation fault
problem. That's interesting. Now what does that tell us about possible
causes? (Zoltan?) And now I can use the Mercury debugger!
> 2. Audit every allocation path around MR_make_aligned_string_copy,
> including C helpers and callbacks.
What do you mean by "allocation path"? And MR_make_aligned_string_copy is
only an example of what seem to be compiler-internals that have been made
use of in the original, unimproved ODBC library. I'll have to audit them
all...
Btw, the original ODBC library is very hacky. Or, you could call it
"advanced". It uses C long-jumps to emulate exception handling... I had to
reimplement the ODBC error handling completely.
> 3. Check source-buffer termination & lifetime (if you can determine it
> robustly) and how returned Mercury strings remain reachable (under
> thevsame provision). This may be the hardest thing to do for parallel
> grades, see why below 5.
What do you mean by "source-buffer"?
> 3. Build with C debug symbols and capture the SIGSEGV in gdb (or a core
> dump), including "thread apply all bt full". Log row number, column,
> buffer capacity and reported length immediately around fetch/copy
> operations. Use AddressSanitizer/UBSan to seek the first invalid access.
Again a phrase I don't understand: "thread apply all bt full"? I don't have
any experience with gdb. But using it here looks like a good idea. But (of
course) I'll try the Mercury debugger first.
What is "AddressSanitizer" and "UBSan"? Gdb features?
> This requires some GDB know-how but knowing your coding mastery, Volker, I
> assume this to be entirely feasible by you.
Yes, it should be.
> Abstracting away from the use case at issue, my prior comparable
> experience and a subsequent plunge into Mercury's memory management
> details have led me to the following conclusions, which admittedly are
> somewhat subjective and so entirely debatable:
> 4. When you investigate how Prologs historically managed memory, you
> discover that memory was initially managed without GC. GNU Prolog
> preallocates memory in excess of actual needs and still does not use GC.
> Scryer Prolog was created using the same (primitive) memory management
> pattern. There is a whole fascinating (though somewhat technically
> outdated) book on the issue about older Prologs, which I am afraid still
> is entirely relevant (Memory Performance of Prolog Architectures, E. Tick,
> Kluwer, 1988 — should be an obligatory must-read to any LP student or
> serious practitioner).
> While Mercury has its own memory management system, there remain common
> issues that are pervasive in all LP programming languages, and make it all
> but impossible to align with Rust-like management of memory chunk
> ownership and lifetime (see Zoltan's reply to a prior thread I initiated a
> few months ago).
You haven't initiated a thread in the past few years... replies only. So
says my mail client.
> 5. While there is some documentation in the repository on how GC memory
> allocation is implemented, I still am at a loss to understand how it
> interacts with parallelism, which is a late move in Mercury and I am not
> sure all issues have been tackled so that, in parallel grades/runs, memory
> (de-)allocation, access to pointers and GC work seamlessly.
That would be *really bad*, if parallelism didn't reliably work in Mercury.
> If ever GDB does not help you out in steps 1-3, there might be a clue in
> 4-5.
Thank you very much for these statements! They look very helpful. But it
still will be a big headache for me.
There's another problem which I need to solve. It's a bug in the Mfwpar
library. It will be much easier to solve, so I'm going to do that first.
Regards,
Volker
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20261021/b31dbd15/attachment.html>
More information about the users
mailing list