From: Michael Schmitz <schmitzmic@gmail.com>
To: Andreas Schwab <schwab@linux-m68k.org>,
Finn Thain <fthain@linux-m68k.org>
Cc: debian-68k@lists.debian.org, linux-m68k@lists.linux-m68k.org
Subject: Re: reliable reproducer, was Re: core dump analysis
Date: Mon, 24 Apr 2023 15:51:49 +1200 [thread overview]
Message-ID: <ee8b7118-2197-0ea2-485f-a87c462384e2@gmail.com> (raw)
In-Reply-To: <87v8hmw9re.fsf@igel.home>
[-- Attachment #1: Type: text/plain, Size: 1549 bytes --]
Hi Andreas,
On 24/04/23 09:48, Andreas Schwab wrote:
> On Apr 24 2023, Michael Schmitz wrote:
>
>> Not sure what third argument you referred to in another mail.
> See struct sigframe and struct rt_sigframe. The non-rt signal handler
> gets signal number, vector number and sigcontext*. The rt signal
> handler gets signal number, siginfo* and ucontext*.
Thanks, I see now. Got confused by the sigaction man page (despite
working out that it's all there on the stack before...). Might need a
comment in the code (or an update to the man pages).
I've rewritten my test program to make the non-rt handler take three
arguments, just to simplify things. Also fixed the end of signal frame
calculation for the non-rt case where the exception places additional
data on the stack.
Running with the non-rt handler, the crash appears to happen right at
the end of the recursion (or at least, I take no further SIGCHLD on the
way back up the stack). With the rt handler, I see the stack depth
decreased on the last signal taken before the crash.
When I enable dumping the extra exception frame contents (which will
show prior stack contents when the exception only used a four-word
frame) in the rt handler case, I only see saved register data placed
there at the very end. That's different from previous tests where I saw
the saved register patterns all the time. (but might have had the
offsets wrong).
I'll see what peeking at the registers shows (now that I can be
confident I have got the offsets correct).
Cheers,
Michael
[-- Attachment #2: movemlrt.c --]
[-- Type: text/x-csrc, Size: 8286 bytes --]
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <ucontext.h>
#include <asm/ptrace.h>
/* how deep at recursion */
int depth = 200000;
const int max_depth = 200000;
/* how deep still on the stack while returning */
int rdepth = 0;
const unsigned long i0 = 0x91929394;
const unsigned long i1 = 0xa1a2a3a4;
const unsigned long i2 = 0xb1b2b3b4;
const unsigned long i3 = 0xc1c2c3c4;
const unsigned long i4 = 0xd1d2d3d4;
const unsigned long i5 = 0xe1e2e3e4;
const unsigned long i6 = 0xf1f2f3f4;
unsigned long o0;
unsigned long o1;
unsigned long o2;
unsigned long o3;
unsigned long o4;
unsigned long o5;
unsigned long o6;
unsigned long parent_usp;
/* extra frame size used for sa_handler case */
static const int frame_size_change[16] = {
[1] = -1, /* sizeof_field(struct frame, un.fmt1), */
[2] = 4, /* sizeof_field(struct frame, un.fmt2), */
[3] = 4, /* sizeof_field(struct frame, un.fmt3), */
[4] = 8, /* sizeof_field(struct frame, un.fmt4), */
[5] = -1, /* sizeof_field(struct frame, un.fmt5), */
[6] = -1, /* sizeof_field(struct frame, un.fmt6), */
[7] = 52, /* sizeof_field(struct frame, un.fmt7), */
[8] = -1, /* sizeof_field(struct frame, un.fmt8), */
[9] = 12, /* sizeof_field(struct frame, un.fmt9), */
[10] = 20, /* sizeof_field(struct frame, un.fmta), */
[11] = 84, /* sizeof_field(struct frame, un.fmtb), */
[12] = -1, /* sizeof_field(struct frame, un.fmtc), */
[13] = -1, /* sizeof_field(struct frame, un.fmtd), */
[14] = -1, /* sizeof_field(struct frame, un.fmte), */
[15] = -1, /* sizeof_field(struct frame, un.fmtf), */
};
static inline int frame_extra_sizes(int f)
{
return frame_size_change[f];
}
static void rec(void)
{
// initialize registers
asm( " move.l %0, %%a2\n"
" move.l %1, %%a3\n"
" move.l %2, %%a4\n"
" move.l %3, %%a5\n"
" move.l %4, %%d2\n"
" move.l %5, %%d3\n"
" move.l %6, %%d4\n"
:
: "m" (i0), "m" (i1), "m" (i2),
"m" (i3), "m" (i4), "m" (i5), "m" (i6)
: "a2", "a3", "a4", "a5", "d2", "d3", "d4"
);
// note current usp
asm( " move.l %%sp, %0\n"
: "=m" (parent_usp)
:
: "memory"
);
// maybe fork a short-lived process
if ((depth & 0x7ff) == 0)
if (fork() == 0)
exit(0);
if (--depth)
rec(); // callee to save & restore registers
// compare register contents
asm( " move.l %%a2, %0\n"
" move.l %%a3, %1\n"
" move.l %%a4, %2\n"
" move.l %%a5, %3\n"
" move.l %%d2, %4\n"
" move.l %%d3, %5\n"
" move.l %%d4, %6\n"
: "=m" (o0), "=m" (o1), "=m" (o2),
"=m" (o3), "=m" (o4), "=m" (o5), "=m" (o6)
:
: "memory" /* "a2", "a3", "a4", "a5", "d2", "d3", "d4" */
);
if (o0 != i0 || o1 != i1 || o2 != i2 ||
o3 != i3 || o4 != i4 || o5 != i5 || o6 != i6)
asm("illegal");
rdepth++;
}
static void handler(int signo, int vector, struct sigcontext *ctx)
{
// use if only taking signo argument
// struct sigcontext *ctx = (struct sigcontext *) ((unsigned long) &signo + 24);
unsigned long *frame = (unsigned long *)((unsigned long) &signo - 4);
if (signo == SIGCHLD) {
unsigned long usp, end_frame, extra;
int i;
asm( " move.l %%sp, %0\n"
: "=m" (usp)
:
: "memory"
);
fprintf(stderr, "stack depth : %d\n", max_depth - depth);
fprintf(stderr, "retn. depth : %d\n", max_depth - rdepth);
fprintf(stderr, "parent usp : 0x%lx\n", parent_usp);
/* top of signal stack - including extra size for
* exception frames longer than four words
*/
// end_frame = (unsigned long) frame + 32 + sizeof(struct sigcontext);
extra = frame_extra_sizes(ctx->sc_formatvec >> 12);
end_frame = (unsigned long) ctx + sizeof(struct sigcontext) + extra;
if (end_frame > parent_usp)
fprintf(stderr, "signal frame overwrote parent usp!\n");
fprintf(stderr, "frame end : 0x%lx\n", end_frame);
fprintf(stderr, "frame start : 0x%lx\n", frame);
fprintf(stderr, "handler usp : 0x%lx\n", usp);
// fprintf(stderr, "signal vec : 0x%lx\n", vector);
fprintf(stderr, "signal usp : 0x%lx\n", ctx->sc_usp);
fprintf(stderr, "signal pc : 0x%lx\n", ctx->sc_pc);
fprintf(stderr, "signal fmtv : 0x%lx\n", ctx->sc_formatvec);
fprintf(stderr, "\n");
}
}
static void rthandler(int signo, siginfo_t *info, void *ucontext)
{
ucontext_t *ctx = (ucontext_t *) ucontext;
unsigned long *frame = (unsigned long *)((unsigned long) &signo - 4);
if (signo == SIGCHLD) {
unsigned long usp, end_frame;
int i;
asm( " move.l %%sp, %0\n"
: "=m" (usp)
:
: "memory"
);
fprintf(stderr, "stack depth : %d\n", max_depth - depth);
fprintf(stderr, "retn. depth : %d\n", max_depth - rdepth);
fprintf(stderr, "parent usp : 0x%lx\n", parent_usp);
/* top of signal stack - extra size for exception
* frames longer than four words follows uc_filler[54]
*/
// end_frame = (unsigned long) info + sizeof(struct siginfo) + sizeof(struct ucontext);
end_frame = (unsigned long) ucontext + sizeof(struct ucontext);
if (end_frame > parent_usp)
fprintf(stderr, "signal stack overwrote parent usp!\n");
fprintf(stderr, "frame end : 0x%lx\n", end_frame);
fprintf(stderr, "frame start : 0x%lx\n", frame);
fprintf(stderr, "handler usp : 0x%lx\n", usp);
fprintf(stderr, "signal usp : 0x%lx\n", ctx->uc_mcontext.gregs[15]);
fprintf(stderr, "signal pc : 0x%lx\n", ctx->uc_mcontext.gregs[16]);
fprintf(stderr, "signal fmtv : 0x%lx\n", ctx->uc_filler[54]);
#if 0
/* dump frame contents not used for exception frame extra */
if (frame_extra_sizes(ctx->uc_filler[54] >> 12) <= 0)
for (i=0; i < 26; i++) {
if ( !(i & 3) ) fprintf(stderr, "\nextra %d\t", i);
fprintf(stderr, "0x%lx\t", ctx->uc_filler[55+i]);
}
#endif
fprintf(stderr, "\n");
#if 0
/* dump stored registers */
fprintf(stderr, "signal stack: 0x%lx\n", ctx->uc_stack.ss_sp);
fprintf(stderr, "signal usp : 0x%lx\n", ctx->uc_mcontext.gregs[15]);
fprintf(stderr, "signal pc : 0x%lx\n", ctx->uc_mcontext.gregs[16]);
fprintf(stderr, "signal f.d1 : 0x%lx\n", ctx->uc_filler[41]);
fprintf(stderr, "signal f.d2 : 0x%lx\n", ctx->uc_filler[42]);
fprintf(stderr, "signal f.d3 : 0x%lx\n", ctx->uc_filler[43]);
fprintf(stderr, "signal f.d4 : 0x%lx\n", ctx->uc_filler[44]);
fprintf(stderr, "signal f.d5 : 0x%lx\n", ctx->uc_filler[45]);
fprintf(stderr, "signal f.a0 : 0x%lx\n", ctx->uc_filler[46]);
fprintf(stderr, "signal f.a1 : 0x%lx\n", ctx->uc_filler[47]);
fprintf(stderr, "signal f.a2 : 0x%lx\n", ctx->uc_filler[48]);
fprintf(stderr, "signal f.d0 : 0x%lx\n", ctx->uc_filler[49]);
fprintf(stderr, "signal f.od0: 0x%lx\n", ctx->uc_filler[50]);
fprintf(stderr, "signal f.sad: 0x%lx\n", ctx->uc_filler[51]);
fprintf(stderr, "signal f.sr : 0x%lx\n", ctx->uc_filler[52]);
fprintf(stderr, "signal f.pc : 0x%lx\n", ctx->uc_filler[53]);
fprintf(stderr, "signal a2 : 0x%lx\n", ctx->uc_mcontext.gregs[10]);
fprintf(stderr, "signal a3 : 0x%lx\n", ctx->uc_mcontext.gregs[11]);
fprintf(stderr, "signal a4 : 0x%lx\n", ctx->uc_mcontext.gregs[12]);
fprintf(stderr, "signal a5 : 0x%lx\n", ctx->uc_mcontext.gregs[13]);
fprintf(stderr, "signal d2 : 0x%lx\n", ctx->uc_mcontext.gregs[2]);
fprintf(stderr, "signal d3 : 0x%lx\n", ctx->uc_mcontext.gregs[3]);
fprintf(stderr, "signal d4 : 0x%lx\n\n", ctx->uc_mcontext.gregs[4]);
#endif
}
}
int main(int use_rt)
{
struct sigaction act;
stack_t ss;
use_rt--;
/* poor man's getopt - use none, one or two args */
fprintf(stderr, "use_rt = %d\n", use_rt);
ss.ss_sp = malloc(SIGSTKSZ);
if (ss.ss_sp == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
ss.ss_size = SIGSTKSZ;
ss.ss_flags = 0;
if (use_rt & 2)
fprintf(stderr, "alt stack 0x%lx - 0x%lx\n", ss.ss_sp, ss.ss_sp + ss.ss_size);
if (sigaltstack(&ss, NULL) == -1) {
perror("sigaltstack");
exit(EXIT_FAILURE);
}
memset(&act, 0, sizeof(act));
sigemptyset(&act.sa_mask);
if (use_rt) {
act.sa_flags = SA_SIGINFO;
if (use_rt & 2)
act.sa_flags |= SA_ONSTACK;
fprintf(stderr, "using sa_sigaction\n");
act.sa_sigaction = rthandler;
} else {
fprintf(stderr, "using sa_handler\n");
act.sa_handler = handler;
}
if (sigaction(SIGCHLD, &act, NULL) == -1) {
perror("sigaction");
exit(EXIT_FAILURE);
}
rec();
}
next prev parent reply other threads:[~2023-04-24 3:52 UTC|newest]
Thread overview: 134+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <4a9c1d0d-07aa-792e-921f-237d5a30fc44.ref@yahoo.com>
[not found] ` <4a9c1d0d-07aa-792e-921f-237d5a30fc44@yahoo.com>
2023-01-30 10:12 ` stack smashing detected Geert Uytterhoeven
2023-01-31 3:05 ` Michael Schmitz
[not found] ` <af524ac9-f5af-e9fb-e33f-0884a0ebfcb6@yahoo.com>
2023-02-01 18:51 ` Michael Schmitz
2023-02-02 7:52 ` Geert Uytterhoeven
[not found] ` <8fb2aa62-dcec-9bd0-b8da-00d9bb4ddaba@yahoo.com>
2023-02-03 0:15 ` Michael Schmitz
2023-02-05 22:19 ` Michael Schmitz
[not found] ` <33d7ea3e-9bd2-16e4-4d9a-f7aa5657a0f7@yahoo.com>
2023-02-07 22:58 ` Michael Schmitz
2023-02-09 3:41 ` Michael Schmitz
[not found] ` <c01e2f1c-425f-478d-918e-cd1fd37e0008@yahoo.com>
[not found] ` <aee359a6-b5e0-fbe2-3988-779f8601f106@gmail.com>
[not found] ` <8042d988-6dd9-8170-60e9-cdf19118440f@yahoo.com>
[not found] ` <a8f06e4b-db28-c8f9-5e21-3ea0f3eebacd@linux-m68k.org>
[not found] ` <bb27b393-3d02-f42c-5c7f-c27d4936ece9@linux-m68k.org>
[not found] ` <37da2ca2-dd99-8417-7cae-a88e2e7fc1b6@yahoo.com>
[not found] ` <30a1be59-a1fd-f882-1072-c7db8734b1f1@gmail.com>
[not found] ` <39f79c2d-e803-d7b1-078f-8757ca9b1238@yahoo.com>
[not found] ` <c47abfdc-31c8-e7ed-1c14-90f68710f25d@gmail.com>
[not found] ` <040ad66a-71dd-001b-0446-36cbd6547b37@yahoo.com>
[not found] ` <5b9d64bb-2adc-20a2-f596-f99bf255b5cc@linux-m68k.org>
[not found] ` <56bd9a33-c58a-58e0-3956-e63c61abe5fe@yahoo.com>
[not found] ` <1725f7c1-2084-a404-653d-9e9f8bbe961c@linux-m68k.org>
2023-03-28 3:37 ` core dump analysis, was " Finn Thain
2023-03-31 3:33 ` Finn Thain
2023-04-01 9:27 ` Finn Thain
2023-04-01 10:11 ` Andreas Schwab
2023-04-02 10:46 ` Finn Thain
2023-04-02 22:01 ` Michael Schmitz
2023-04-04 0:13 ` Finn Thain
2023-04-04 23:22 ` Michael Schmitz
2023-04-05 2:00 ` Finn Thain
2023-04-07 1:57 ` Michael Schmitz
2023-04-07 4:03 ` dash behaviour, was Re: core dump analysis Finn Thain
2023-04-07 12:10 ` Geert Uytterhoeven
2023-04-08 5:29 ` Finn Thain
2023-04-09 8:30 ` Geert Uytterhoeven
2023-04-09 3:48 ` Michael Schmitz
2023-04-09 4:42 ` Finn Thain
2023-04-09 4:55 ` Michael Schmitz
2023-04-09 7:32 ` Finn Thain
2023-04-10 8:12 ` Michael Schmitz
2023-04-10 9:39 ` kernel behaviour, was Re: dash behaviour Finn Thain
2023-04-11 4:29 ` Michael Schmitz
2023-04-11 4:50 ` Finn Thain
2023-04-11 7:21 ` Geert Uytterhoeven
2023-04-07 12:06 ` core dump analysis, was Re: stack smashing detected Geert Uytterhoeven
2023-04-09 1:56 ` Michael Schmitz
2023-04-11 0:20 ` instrumentation, was Re: core dump analysis Finn Thain
2023-04-11 4:56 ` Michael Schmitz
2023-04-11 5:54 ` Finn Thain
2023-04-11 7:19 ` Geert Uytterhoeven
2023-04-11 8:24 ` Michael Schmitz
2023-04-12 23:22 ` Eero Tamminen
2023-04-15 15:50 ` Eero Tamminen
2023-04-15 21:56 ` Brad Boyer
2023-04-14 9:30 ` core dump analysis, was Re: stack smashing detected Finn Thain
2023-04-16 1:50 ` Michael Schmitz
2023-04-16 6:44 ` Finn Thain
2023-04-17 23:32 ` Michael Schmitz
2023-04-18 2:04 ` Finn Thain
2023-04-18 5:29 ` Michael Schmitz
2023-04-19 1:50 ` Finn Thain
2023-04-19 8:15 ` Michael Schmitz
2023-04-23 7:46 ` Finn Thain
2023-04-23 21:26 ` Michael Schmitz
2023-04-19 10:50 ` reliable reproducer, was Re: core dump analysis Finn Thain
2023-04-19 11:55 ` Geert Uytterhoeven
2023-04-20 1:02 ` Finn Thain
2023-04-20 0:55 ` Michael Schmitz
2023-04-20 2:57 ` Finn Thain
2023-04-20 4:08 ` Michael Schmitz
2023-04-20 5:17 ` Finn Thain
2023-04-20 5:48 ` Finn Thain
2023-04-20 7:34 ` Michael Schmitz
2023-04-20 7:47 ` Finn Thain
2023-04-20 8:23 ` Michael Schmitz
2023-04-20 8:55 ` Finn Thain
2023-04-20 21:58 ` Michael Schmitz
2023-04-21 1:45 ` Michael Schmitz
2023-04-21 5:52 ` Michael Schmitz
2023-04-21 8:30 ` Finn Thain
2023-04-21 9:18 ` Michael Schmitz
2023-04-22 7:54 ` Michael Schmitz
2023-04-22 8:07 ` Andreas Schwab
2023-04-22 8:16 ` Michael Schmitz
2023-04-22 10:12 ` Andreas Schwab
2023-04-22 18:24 ` Michael Schmitz
2023-04-22 18:38 ` Andreas Schwab
2023-04-22 20:06 ` Michael Schmitz
2023-04-22 20:46 ` Andreas Schwab
2023-04-23 1:41 ` Michael Schmitz
2023-04-23 7:37 ` Andreas Schwab
2023-04-23 8:18 ` Michael Schmitz
2023-04-23 8:23 ` Andreas Schwab
2023-04-23 20:19 ` Michael Schmitz
2023-04-23 21:48 ` Andreas Schwab
2023-04-24 3:51 ` Michael Schmitz [this message]
2023-04-24 5:46 ` Michael Schmitz
2023-04-23 9:23 ` Finn Thain
2023-04-23 20:43 ` Michael Schmitz
2023-04-24 23:44 ` Finn Thain
[not found] ` <1d9955d2-6016-a238-142a-887f95465dd8@linux-m68k.org>
[not found] ` <4763c8e2-6fb3-eda6-10d0-94ed1d01cd60@gmail.com>
[not found] ` <a5d70bac-bd00-7131-9ca0-18976f539adf@linux-m68k.org>
[not found] ` <b150c146-cade-bcd3-9c34-d99284dcd153@gmail.com>
[not found] ` <c3d2d874-e366-1d3b-71b0-7a089d40308a@linux-m68k.org>
2023-04-25 1:55 ` signal delivery, was Re: reliable reproducer Finn Thain
2023-04-25 2:32 ` Michael Schmitz
2023-04-25 5:59 ` Michael Schmitz
2023-04-26 19:45 ` Michael Schmitz
[not found] ` <1c4fc19f-ad9b-7b8f-6638-8b026fe1280b@linux-m68k.org>
[not found] ` <5ac55169-4916-d671-489f-7eb8fb85d336@gmail.com>
[not found] ` <9544ef26-a444-e186-fb1e-0e914acd36af@gmail.com>
[not found] ` <20de24b3-098d-4603-2768-b0468a4fe772@gmail.com>
[not found] ` <69565abb-1cd6-716e-046e-5a6d69a4e617@linux-m68k.org>
[not found] ` <89cb2211-5f6e-07a2-3149-1ad1ad887265@linux-m68k.org>
[not found] ` <d3d27369-8532-ba69-2463-66b8decbee67@gmail.com>
[not found] ` <4b4eacf2-6934-5563-fb47-04843a77a35c@gmail.com>
2023-04-29 0:28 ` Finn Thain
2023-04-29 0:53 ` Finn Thain
2023-04-29 2:53 ` Michael Schmitz
2023-04-29 5:03 ` Finn Thain
2023-04-29 6:01 ` Michael Schmitz
2023-04-29 6:13 ` Finn Thain
2023-04-29 6:43 ` Michael Schmitz
2023-04-29 6:05 ` Finn Thain
2023-04-29 7:11 ` Andreas Schwab
2023-04-29 7:37 ` Michael Schmitz
2023-04-25 9:26 ` Eero Tamminen
2023-04-25 11:25 ` Andreas Schwab
2023-04-25 19:46 ` Michael Schmitz
2023-04-26 1:54 ` Michael Schmitz
2023-04-26 3:27 ` Finn Thain
2023-04-26 3:56 ` Michael Schmitz
2023-04-26 4:53 ` Finn Thain
2023-04-26 2:02 ` Finn Thain
2023-04-26 4:00 ` Michael Schmitz
2023-04-26 4:42 ` Finn Thain
2023-04-26 9:10 ` Michael Schmitz
2023-04-26 21:48 ` Brad Boyer
2023-04-26 8:31 ` Andreas Schwab
2023-04-25 11:53 ` Andreas Schwab
2023-04-26 1:59 ` Finn Thain
2023-04-25 5:18 ` reliable reproducer, was Re: core dump analysis Michael Schmitz
2023-04-22 9:00 ` Michael Schmitz
2023-04-21 1:15 ` Finn Thain
2023-04-21 1:57 ` Michael Schmitz
2023-04-21 1:39 ` Finn Thain
2023-04-20 6:04 ` Finn Thain
2023-04-20 7:40 ` Michael Schmitz
2023-04-20 7:58 ` Finn Thain
2023-04-02 4:09 ` core dump analysis, was Re: stack smashing detected Michael Schmitz
2023-04-02 9:31 ` Finn Thain
2023-04-03 8:26 ` Michael Schmitz
2023-04-04 4:05 ` Finn Thain
2023-04-04 11:05 ` Finn Thain
2023-04-09 4:02 ` Finn Thain
2023-02-03 23:39 ` Finn Thain
[not found] ` <86badf6e-2cc8-1937-1a2f-45334bb338f4@yahoo.com>
2023-02-05 22:29 ` Debian initramfs/initrd, was " Finn Thain
2023-02-05 23:18 ` John Paul Adrian Glaubitz
[not found] ` <8107e04f-fd60-c6e3-2bad-cc0d99877967@yahoo.com>
2023-02-06 7:52 ` Geert Uytterhoeven
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ee8b7118-2197-0ea2-485f-a87c462384e2@gmail.com \
--to=schmitzmic@gmail.com \
--cc=debian-68k@lists.debian.org \
--cc=fthain@linux-m68k.org \
--cc=linux-m68k@lists.linux-m68k.org \
--cc=schwab@linux-m68k.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox