Dear Maintainer, We have managed to get a unique IDs (without multi-thread). Hope this could help to get a reproducible build.
Now the ID is generated by a ptr diff. val = (long)((char *)cur - (char *)&base_address); cur is the address of a xmlNsPtr node stored in a hash table(of course, eventually it's in the heap), base_address is a static variable(in a data section); After some debug, we found there are two major disturbances that prevent a reproducible build. First, hash functions use a random seed get from time(). So the address of nodes in hash tables(related to cur) is not stable across multi-builds. Second, ASLR (Address Space Layout Randomization) changes the base addresses of data section and heap every time we start a new process. To fix the first problem, we could fake a fixed time. We currently use libfaketime, and of course eventually something like https://gitlab.gnome.org/GNOME/libxslt/commit/e57df303eca25a2a3f9e0625c29f4b20177858cc should be applied. To fix the second problem, we could change the ptr diff algorithm to val = (long)((char *)cur - heapStartAddr); After this change, ALSR could not disturb ID generation anymore, because we have eliminated the base address of heap. ========================================================================================================== We have use the following patch to make the xlstproc produce stable IDs. --- libxslt-master/libxslt/functions.c 2010-12-24 20:30:00.000000000 +0800 +++ libxslt-master-new/libxslt/functions.c 2010-12-24 20:30:00.000000000 +0800 @@ -14,7 +14,7 @@ #include "libxslt.h" #include <string.h> - +#include <unistd.h> #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif @@ -671,6 +671,13 @@ xsltFormatNumberFunction(xmlXPathParserC xmlXPathFreeObject(decimalObj); } + +static char *__heapStartAddr; +static __attribute__((constructor)) void initHeapStart() +{ + __heapStartAddr = sbrk(0); +} + /** * xsltGenerateIdFunction: * @ctxt: the XPath Parser context @@ -681,7 +688,6 @@ xsltFormatNumberFunction(xmlXPathParserC */ void xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ - static char base_address; xmlNodePtr cur = NULL; xmlXPathObjectPtr obj = NULL; long val; @@ -722,7 +728,8 @@ xsltGenerateIdFunction(xmlXPathParserCon if (obj) xmlXPathFreeObject(obj); - val = (long)((char *)cur - (char *)&base_address); + val = (long)((char *)cur - __heapStartAddr); + if (val >= 0) { snprintf((char *)str, sizeof(str), "idp%ld", val); } else {