Download raw body.
got fails to build on alpha
On Fri, Oct 09, 2026 at 04:41:19PM +0200, Theo Buehler wrote:
> On Fri, Oct 09, 2026 at 04:39:03PM +0200, Stefan Sperling wrote:
> > This looks like something Miod might be qualified to take a look at?
>
> These files both have pretty huge structures on the stack. Might this be
> releated?
In that case, the following diff might help:
move buffers of size GOT_PKT_MAX off the stack
M lib/serve.c | 130+ 45-
M libexec/got-fetch-pack/got-fetch-pack.c | 19+ 12-
M libexec/got-send-pack/got-send-pack.c | 12+ 6-
3 files changed, 161 insertions(+), 63 deletions(-)
commit - 10f51ecc4cbfab15f63d68920c9674a2995fd394
commit + 22805600d8994acd612c568d0013c48a4476e16d
blob - d87245ee471ce963a0c8b81e4d9fc75c03a378d8
blob + 219c75af8f0167f9d23332b05bfc92d93cfcd7bf
--- lib/serve.c
+++ lib/serve.c
@@ -120,36 +120,48 @@ send_ref(int outfd, uint8_t *id, const char *refname,
{
const struct got_error *err = NULL;
char hex[GOT_HASH_DIGEST_STRING_MAXLEN];
- char buf[GOT_PKT_MAX];
+ char *buf = NULL;
+ const size_t bufsize = GOT_PKT_MAX;
size_t len, capalen = 0;
if (got_hash_digest_to_str(id, hex, sizeof(hex), algo) == NULL)
return got_error(GOT_ERR_BAD_OBJ_ID);
- len = snprintf(buf, sizeof(buf), "%s %s", hex, refname);
- if (len >= sizeof(buf))
- return got_error(GOT_ERR_NO_SPACE);
+ buf = calloc(1, bufsize);
+ if (buf == NULL)
+ return got_error_from_errno("calloc");
+ len = snprintf(buf, bufsize, "%s %s", hex, refname);
+ if (len >= bufsize) {
+ err = got_error(GOT_ERR_NO_SPACE);
+ goto done;
+ }
+
if (send_capabilities) {
if (client_is_reading) {
err = append_read_capabilities(&capalen, len,
- symrefstr, buf, sizeof(buf), algo);
+ symrefstr, buf, bufsize, algo);
} else {
err = append_write_capabilities(&capalen, len,
- symrefstr, buf, sizeof(buf), algo);
+ symrefstr, buf, bufsize, algo);
}
if (err)
- return err;
+ goto done;
len += capalen;
}
- if (len + 1 >= sizeof(buf))
- return got_error(GOT_ERR_NO_SPACE);
+ if (len + 1 >= bufsize) {
+ err = got_error(GOT_ERR_NO_SPACE);
+ goto done;
+ }
buf[len] = '\n';
len++;
buf[len] = '\0';
- return got_pkt_writepkt(outfd, buf, len, chattygot);
+ err = got_pkt_writepkt(outfd, buf, len, chattygot);
+done:
+ free(buf);
+ return err;
}
static const struct got_error *
@@ -157,7 +169,8 @@ send_zero_refs(int outfd, int client_is_reading, int c
{
const struct got_error *err = NULL;
const char *line;
- char buf[GOT_PKT_MAX];
+ char *buf = NULL;
+ const size_t bufsize = GOT_PKT_MAX;
size_t len, capalen = 0;
if (algo == GOT_HASH_SHA1)
@@ -167,23 +180,32 @@ send_zero_refs(int outfd, int client_is_reading, int c
else
return got_error(GOT_ERR_OBJECT_FORMAT);
- len = strlcpy(buf, line, sizeof(buf));
- if (len >= sizeof(buf))
- return got_error(GOT_ERR_NO_SPACE);
+ buf = calloc(1, bufsize);
+ if (buf == NULL)
+ return got_error_from_errno("calloc");
+ len = strlcpy(buf, line, bufsize);
+ if (len >= bufsize) {
+ err = got_error(GOT_ERR_NO_SPACE);
+ goto done;
+ }
+
if (client_is_reading) {
err = append_read_capabilities(&capalen, len,
- NULL, buf, sizeof(buf), algo);
+ NULL, buf, bufsize, algo);
if (err)
- return err;
+ goto done;
} else {
err = append_write_capabilities(&capalen, len,
- NULL, buf, sizeof(buf), algo);
+ NULL, buf, bufsize, algo);
if (err)
- return err;
+ goto done;
}
- return got_pkt_writepkt(outfd, buf, len + capalen, chattygot);
+ err = got_pkt_writepkt(outfd, buf, len + capalen, chattygot);
+done:
+ free(buf);
+ return err;
}
static void
@@ -719,18 +741,29 @@ done:
static const struct got_error *
send_ack(int outfd, uint8_t *id, int chattygot, int algo)
{
+ const struct got_error *err = NULL;
char hex[GOT_HASH_DIGEST_STRING_MAXLEN];
- char buf[GOT_PKT_MAX];
+ char *buf = NULL;
+ const size_t bufsize = GOT_PKT_MAX;
int len;
if (got_hash_digest_to_str(id, hex, sizeof(hex), algo) == NULL)
return got_error(GOT_ERR_BAD_OBJ_ID);
- len = snprintf(buf, sizeof(buf), "ACK %s\n", hex);
- if (len >= sizeof(buf))
- return got_error(GOT_ERR_NO_SPACE);
+ buf = calloc(1, bufsize);
+ if (buf == NULL)
+ return got_error_from_errno("calloc");
- return got_pkt_writepkt(outfd, buf, len, chattygot);
+ len = snprintf(buf, bufsize, "ACK %s\n", hex);
+ if (len >= bufsize) {
+ err = got_error(GOT_ERR_NO_SPACE);
+ goto done;
+ }
+
+ err = got_pkt_writepkt(outfd, buf, len, chattygot);
+done:
+ free(buf);
+ return err;
}
static const struct got_error *
@@ -868,7 +901,8 @@ relay_progress_reports(struct imsgbuf *ibuf, int outfd
const struct got_error *err = NULL;
int pack_starting = 0;
struct gotd_imsg_packfile_progress iprog;
- char buf[GOT_PKT_MAX];
+ char *buf = NULL;
+ const size_t bufsize = GOT_PKT_MAX;
struct imsg imsg;
size_t datalen;
int p_deltify = 0, n;
@@ -876,6 +910,10 @@ relay_progress_reports(struct imsgbuf *ibuf, int outfd
memset(&imsg, 0, sizeof(imsg));
+ buf = calloc(1, bufsize);
+ if (buf == NULL)
+ return got_error_from_errno("calloc");
+
while (!pack_starting && err == NULL) {
err = gotd_imsg_poll_recv(&imsg, ibuf, 0);
if (err)
@@ -901,14 +939,14 @@ relay_progress_reports(struct imsgbuf *ibuf, int outfd
iprog.nobj_total;
}
buf[0] = GOT_SIDEBAND_PROGRESS_INFO;
- n = snprintf(&buf[1], sizeof(buf) - 1,
+ n = snprintf(&buf[1], bufsize - 1,
"%d commits colored, "
"%d objects found, "
"deltify %d%%%s",
iprog.ncolored,
iprog.nfound,
p_deltify, eol);
- if (n >= sizeof(buf) - 1)
+ if (n >= bufsize - 1)
break;
err = got_pkt_writepkt(outfd, buf, 1 + n, chattygot);
break;
@@ -920,6 +958,7 @@ relay_progress_reports(struct imsgbuf *ibuf, int outfd
imsg_free(&imsg);
}
+ free(buf);
return err;
}
@@ -928,7 +967,8 @@ serve_read(int infd, int outfd, int gotd_sock, const c
int chattygot)
{
const struct got_error *err = NULL;
- char buf[GOT_PKT_MAX];
+ char *buf = NULL;
+ const size_t bufsize = GOT_PKT_MAX;
struct imsgbuf ibuf;
enum protostate {
STATE_EXPECT_WANT,
@@ -945,6 +985,12 @@ serve_read(int infd, int outfd, int gotd_sock, const c
return got_error_from_errno("imsgbuf_init");
imsgbuf_allow_fdpass(&ibuf);
+ buf = calloc(1, bufsize);
+ if (buf == NULL) {
+ err = got_error_from_errno("calloc");
+ goto done;
+ }
+
err = announce_refs(outfd, &algo, &ibuf, 1, repo_path, chattygot);
if (err)
goto done;
@@ -952,7 +998,7 @@ serve_read(int infd, int outfd, int gotd_sock, const c
while (curstate != STATE_DONE) {
int n;
- err = got_pkt_readpkt(&n, infd, buf, sizeof(buf), chattygot,
+ err = got_pkt_readpkt(&n, infd, buf, bufsize, chattygot,
timeout);
if (err)
goto done;
@@ -972,7 +1018,7 @@ serve_read(int infd, int outfd, int gotd_sock, const c
* anything we should receive a flush
* packet followed by EOF.
*/
- r = read(infd, buf, sizeof(buf));
+ r = read(infd, buf, bufsize);
if (r == -1) {
err = got_error_from_errno("read");
goto done;
@@ -1056,7 +1102,7 @@ serve_read(int infd, int outfd, int gotd_sock, const c
goto done;
pack_chunksize = GOT_SIDEBAND_64K_PACKFILE_DATA_MAX;
} else
- pack_chunksize = sizeof(buf);
+ pack_chunksize = bufsize;
for (;;) {
ssize_t r;
@@ -1087,6 +1133,7 @@ serve_read(int infd, int outfd, int gotd_sock, const c
}
done:
imsgbuf_clear(&ibuf);
+ free(buf);
if (packfd != -1 && close(packfd) == -1 && err == NULL)
err = got_error_from_errno("close");
if (err)
@@ -1245,7 +1292,8 @@ recv_packfile(struct imsg *imsg, struct imsgbuf *ibuf,
const struct got_error *err = NULL;
size_t datalen;
int packfd;
- char buf[GOT_PKT_MAX];
+ char *buf = NULL;
+ const size_t bufsize = GOT_PKT_MAX;
int pack_done = 0;
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
@@ -1264,6 +1312,10 @@ recv_packfile(struct imsg *imsg, struct imsgbuf *ibuf,
if (err)
return err;
+ buf = calloc(1, bufsize);
+ if (buf == NULL)
+ return got_error_from_errno("calloc");
+
while (!pack_done) {
ssize_t r = 0;
@@ -1273,7 +1325,7 @@ recv_packfile(struct imsg *imsg, struct imsgbuf *ibuf,
break;
err = NULL;
} else {
- r = read(infd, buf, sizeof(buf));
+ r = read(infd, buf, bufsize);
if (r == -1) {
err = got_error_from_errno("read");
break;
@@ -1312,6 +1364,7 @@ recv_packfile(struct imsg *imsg, struct imsgbuf *ibuf,
}
close(packfd);
+ free(buf);
return err;
}
@@ -1320,7 +1373,8 @@ report_unpack_status(struct imsg *imsg, int outfd, int
{
const struct got_error *err = NULL;
struct gotd_imsg_packfile_status istatus;
- char buf[GOT_PKT_MAX];
+ char *buf = NULL;
+ const size_t bufsize = GOT_PKT_MAX;
size_t datalen, len;
char *reason = NULL;
@@ -1337,11 +1391,17 @@ report_unpack_status(struct imsg *imsg, int outfd, int
goto done;
}
+ buf = calloc(1, bufsize);
+ if (buf == NULL) {
+ err = got_error_from_errno("calloc");
+ goto done;
+ }
+
if (err == NULL)
- len = snprintf(buf, sizeof(buf), "unpack ok\n");
+ len = snprintf(buf, bufsize, "unpack ok\n");
else
- len = snprintf(buf, sizeof(buf), "unpack %s\n", reason);
- if (len >= sizeof(buf)) {
+ len = snprintf(buf, bufsize, "unpack %s\n", reason);
+ if (len >= bufsize) {
err = got_error(GOT_ERR_NO_SPACE);
goto done;
}
@@ -1349,6 +1409,7 @@ report_unpack_status(struct imsg *imsg, int outfd, int
err = got_pkt_writepkt(outfd, buf, len, chattygot);
done:
free(reason);
+ free(buf);
return err;
}
@@ -1358,7 +1419,8 @@ recv_ref_update_ok(struct imsg *imsg, int outfd, int c
const struct got_error *err = NULL;
struct gotd_imsg_ref_update_ok iok;
size_t datalen, len;
- char buf[GOT_PKT_MAX];
+ char *buf = NULL;
+ const size_t bufsize = GOT_PKT_MAX;
char *refname = NULL;
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
@@ -1377,8 +1439,14 @@ recv_ref_update_ok(struct imsg *imsg, int outfd, int c
if (refname == NULL)
return got_error_from_errno("strndup");
- len = snprintf(buf, sizeof(buf), "ok %s\n", refname);
- if (len >= sizeof(buf)) {
+ buf = calloc(1, bufsize);
+ if (buf == NULL) {
+ err = got_error_from_errno("calloc");
+ goto done;
+ }
+
+ len = snprintf(buf, bufsize, "ok %s\n", refname);
+ if (len >= bufsize) {
err = got_error(GOT_ERR_NO_SPACE);
goto done;
}
@@ -1386,6 +1454,7 @@ recv_ref_update_ok(struct imsg *imsg, int outfd, int c
err = got_pkt_writepkt(outfd, buf, len, chattygot);
done:
free(refname);
+ free(buf);
return err;
}
@@ -1395,7 +1464,8 @@ recv_ref_update_ng(struct imsg *imsg, int outfd, int c
const struct got_error *err = NULL;
struct gotd_imsg_ref_update_ng ing;
size_t datalen, len;
- char buf[GOT_PKT_MAX];
+ char *buf = NULL;
+ const size_t bufsize = GOT_PKT_MAX;
char *refname = NULL, *reason = NULL;
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
@@ -1421,8 +1491,14 @@ recv_ref_update_ng(struct imsg *imsg, int outfd, int c
goto done;
}
- len = snprintf(buf, sizeof(buf), "ng %s %s\n", refname, reason);
- if (len >= sizeof(buf)) {
+ buf = calloc(1, bufsize);
+ if (buf == NULL) {
+ err = got_error_from_errno("calloc");
+ goto done;
+ }
+
+ len = snprintf(buf, bufsize, "ng %s %s\n", refname, reason);
+ if (len >= bufsize) {
err = got_error(GOT_ERR_NO_SPACE);
goto done;
}
@@ -1431,6 +1507,7 @@ recv_ref_update_ng(struct imsg *imsg, int outfd, int c
done:
free(refname);
free(reason);
+ free(buf);
return err;
}
@@ -1439,7 +1516,8 @@ serve_write(int infd, int outfd, int gotd_sock, const
int chattygot)
{
const struct got_error *err = NULL;
- char buf[GOT_PKT_MAX];
+ char *buf = NULL;
+ const size_t bufsize = GOT_PKT_MAX;
struct imsgbuf ibuf;
enum protostate {
STATE_EXPECT_REF_UPDATE,
@@ -1466,10 +1544,16 @@ serve_write(int infd, int outfd, int gotd_sock, const
digest_string_length = got_hash_digest_string_length(algo) - 1;
+ buf = calloc(1, bufsize);
+ if (buf == NULL) {
+ err = got_error_from_errno("calloc");
+ goto done;
+ }
+
while (curstate != STATE_EXPECT_PACKFILE) {
int n;
- err = got_pkt_readpkt(&n, infd, buf, sizeof(buf), chattygot,
+ err = got_pkt_readpkt(&n, infd, buf, bufsize, chattygot,
timeout);
if (err)
goto done;
@@ -1578,6 +1662,7 @@ serve_write(int infd, int outfd, int gotd_sock, const
}
done:
imsgbuf_clear(&ibuf);
+ free(buf);
if (err)
echo_error(err, outfd, chattygot);
return err;
blob - 20247f76f92f51c1759606ed18bdaacf4b778b5d
blob + 6deeaf239393baa41b21a264b91e12cd2aeaa629
--- libexec/got-fetch-pack/got-fetch-pack.c
+++ libexec/got-fetch-pack/got-fetch-pack.c
@@ -353,7 +353,8 @@ fetch_pack(int fd, int packfd, int expected_algo,
int no_head, struct imsgbuf *ibuf)
{
const struct got_error *err = NULL;
- char buf[GOT_PKT_MAX];
+ char *buf = NULL;
+ const size_t bufsize = GOT_PKT_MAX;
char hashstr[GOT_HASH_DIGEST_STRING_MAXLEN];
struct got_object_id *have, *want;
int is_firstpkt = 1, nref = 0, refsz = 16;
@@ -388,8 +389,14 @@ fetch_pack(int fd, int packfd, int expected_algo,
err = got_error_from_errno("malloc");
goto done;
}
+
+ buf = calloc(1, bufsize);
+ if (buf == NULL) {
+ err = got_error_from_errno("calloc");
+ goto done;
+ }
while (1) {
- err = got_pkt_readpkt(&n, fd, buf, sizeof(buf), chattygot,
+ err = got_pkt_readpkt(&n, fd, buf, bufsize, chattygot,
INFTIM);
if (err)
goto done;
@@ -652,10 +659,10 @@ fetch_pack(int fd, int packfd, int expected_algo,
if (got_object_id_cmp(&have[i], &want[i]) == 0)
continue;
got_object_id_hex(&want[i], hashstr, sizeof(hashstr));
- n = snprintf(buf, sizeof(buf), "want %s%s\n", hashstr,
+ n = snprintf(buf, bufsize, "want %s%s\n", hashstr,
sent_my_capabilites || my_capabilities == NULL ?
"" : my_capabilities);
- if (n < 0 || (size_t)n >= sizeof(buf)) {
+ if (n < 0 || (size_t)n >= bufsize) {
err = got_error(GOT_ERR_NO_SPACE);
goto done;
}
@@ -675,8 +682,8 @@ fetch_pack(int fd, int packfd, int expected_algo,
RB_FOREACH(pe, got_pathlist_head, have_refs) {
struct got_object_id *id = pe->data;
got_object_id_hex(id, hashstr, sizeof(hashstr));
- n = snprintf(buf, sizeof(buf), "have %s\n", hashstr);
- if (n < 0 || (size_t)n >= sizeof(buf)) {
+ n = snprintf(buf, bufsize, "have %s\n", hashstr);
+ if (n < 0 || (size_t)n >= bufsize) {
err = got_error(GOT_ERR_NO_SPACE);
goto done;
}
@@ -686,7 +693,7 @@ fetch_pack(int fd, int packfd, int expected_algo,
nhave++;
}
- n = strlcpy(buf, "done\n", sizeof(buf));
+ n = strlcpy(buf, "done\n", bufsize);
err = got_pkt_writepkt(fd, buf, n, chattygot);
if (err)
goto done;
@@ -695,7 +702,7 @@ fetch_pack(int fd, int packfd, int expected_algo,
struct got_object_id common_id;
/* The server should ACK the object IDs we need. */
- err = got_pkt_readpkt(&n, fd, buf, sizeof(buf), chattygot,
+ err = got_pkt_readpkt(&n, fd, buf, bufsize, chattygot,
INFTIM);
if (err)
goto done;
@@ -725,7 +732,7 @@ fetch_pack(int fd, int packfd, int expected_algo,
}
if (nhave == 0) {
- err = got_pkt_readpkt(&n, fd, buf, sizeof(buf), chattygot,
+ err = got_pkt_readpkt(&n, fd, buf, bufsize, chattygot,
INFTIM);
if (err)
goto done;
@@ -765,7 +772,7 @@ fetch_pack(int fd, int packfd, int expected_algo,
"short packet");
goto done;
}
- if (datalen > sizeof(buf) - 5) {
+ if (datalen > bufsize - 5) {
err = got_error_msg(GOT_ERR_BAD_PACKET,
"bad packet length");
goto done;
@@ -837,7 +844,7 @@ fetch_pack(int fd, int packfd, int expected_algo,
/* No sideband channel. Every byte is packfile data. */
size_t n = 0;
err = got_poll_read_full_timeout(fd, &n,
- buf, sizeof buf, 1, INFTIM);
+ buf, bufsize, 1, INFTIM);
if (err) {
if (err->code != GOT_ERR_EOF)
goto done;
@@ -944,10 +951,10 @@ done:
free(server_capabilities);
free(my_capabilities);
free(capa);
+ free(buf);
return err;
}
-
int
main(int argc, char **argv)
{
blob - 9b55995e8bfe3159fd77915039d230d0c67df493
blob + e15fe4f0b9c0f13627f4a132eaa7a9841f0d3f06
--- libexec/got-send-pack/got-send-pack.c
+++ libexec/got-send-pack/got-send-pack.c
@@ -345,7 +345,8 @@ send_pack(int fd, enum got_hash_algorithm algo, struct
struct got_pathlist_head *delete_refs, struct imsgbuf *ibuf)
{
const struct got_error *err = NULL;
- char buf[GOT_PKT_MAX];
+ char *buf = NULL;
+ const size_t bufsize = GOT_PKT_MAX;
const unsigned char zero_id[GOT_HASH_DIGEST_MAXLEN] = { 0 };
char old_hashstr[GOT_HASH_DIGEST_STRING_MAXLEN];
char new_hashstr[GOT_HASH_DIGEST_STRING_MAXLEN];
@@ -366,8 +367,12 @@ send_pack(int fd, enum got_hash_algorithm algo, struct
if (RB_EMPTY(refs) && RB_EMPTY(delete_refs))
return got_error(GOT_ERR_SEND_EMPTY);
+ buf = calloc(1, bufsize);
+ if (buf == NULL)
+ return got_error_from_errno("calloc");
+
while (1) {
- err = got_pkt_readpkt(&n, fd, buf, sizeof(buf), chattygot,
+ err = got_pkt_readpkt(&n, fd, buf, bufsize, chattygot,
INFTIM);
if (err)
goto done;
@@ -526,7 +531,7 @@ send_pack(int fd, enum got_hash_algorithm algo, struct
got_hash_digest_to_str(zero_id, new_hashstr,
sizeof(new_hashstr), algo);
err = describe_refchange(&n, &sent_my_capabilites,
- my_capabilities, buf, sizeof(buf), refname,
+ my_capabilities, buf, bufsize, refname,
old_hashstr, new_hashstr);
if (err)
goto done;
@@ -571,7 +576,7 @@ send_pack(int fd, enum got_hash_algorithm algo, struct
}
got_object_id_hex(id, new_hashstr, sizeof(new_hashstr));
err = describe_refchange(&n, &sent_my_capabilites,
- my_capabilities, buf, sizeof(buf), refname,
+ my_capabilities, buf, bufsize, refname,
old_hashstr, new_hashstr);
if (err)
goto done;
@@ -608,7 +613,7 @@ send_pack(int fd, enum got_hash_algorithm algo, struct
goto done;
}
- err = got_pkt_readpkt(&n, fd, buf, sizeof(buf), chattygot, INFTIM);
+ err = got_pkt_readpkt(&n, fd, buf, bufsize, chattygot, INFTIM);
if (err)
goto done;
if (n >= 4 && strncmp(buf, "ERR ", 4) == 0) {
@@ -621,7 +626,7 @@ send_pack(int fd, enum got_hash_algorithm algo, struct
}
while (nsent > 0) {
- err = got_pkt_readpkt(&n, fd, buf, sizeof(buf), chattygot,
+ err = got_pkt_readpkt(&n, fd, buf, bufsize, chattygot,
INFTIM);
if (err)
goto done;
@@ -659,6 +664,7 @@ done:
free(server_capabilities);
free(my_capabilities);
free(capa);
+ free(buf);
return err;
}
got fails to build on alpha