43 lines
1.6 KiB
Diff
43 lines
1.6 KiB
Diff
|
|
From 42dbe9e2ced74ae7f0f3b70daabf634edf44d3d3 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||
|
|
Date: Thu, 13 Jun 2019 23:16:43 +0800
|
||
|
|
Subject: [PATCH] issue-1122: fix bus error on aarch64
|
||
|
|
|
||
|
|
According to the ARMv8 Instruction Set Overview, among other documents,
|
||
|
|
"... if SP is used as the base register then the value of the stack
|
||
|
|
pointer prior to adding any offset must be quadword (16 byte) aligned,
|
||
|
|
or else a stack alignment exception will be generated.". So, we pass
|
||
|
|
the child_stack 16 byte aligned to sys_clone.
|
||
|
|
|
||
|
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||
|
|
---
|
||
|
|
src/base/linuxthreads.cc | 5 ++++-
|
||
|
|
1 file changed, 4 insertions(+), 1 deletion(-)
|
||
|
|
|
||
|
|
diff --git a/src/base/linuxthreads.cc b/src/base/linuxthreads.cc
|
||
|
|
index 891e70c..00b1ea3 100644
|
||
|
|
--- a/src/base/linuxthreads.cc
|
||
|
|
+++ b/src/base/linuxthreads.cc
|
||
|
|
@@ -105,6 +105,7 @@ static int local_clone (int (*fn)(void *), void *arg, ...)
|
||
|
|
#define CLONE_STACK_SIZE 4096
|
||
|
|
#endif
|
||
|
|
|
||
|
|
+#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
|
||
|
|
static int local_clone (int (*fn)(void *), void *arg, ...) {
|
||
|
|
/* Leave 4kB of gap between the callers stack and the new clone. This
|
||
|
|
* should be more than sufficient for the caller to call waitpid() until
|
||
|
|
@@ -120,7 +121,9 @@ static int local_clone (int (*fn)(void *), void *arg, ...) {
|
||
|
|
* is being debugged. This is OK and the error code will be reported
|
||
|
|
* correctly.
|
||
|
|
*/
|
||
|
|
- return sys_clone(fn, (char *)&arg - CLONE_STACK_SIZE,
|
||
|
|
+ void *child_stack = (void *)ALIGN(((unsigned long)&arg - CLONE_STACK_SIZE),
|
||
|
|
+ 16);
|
||
|
|
+ return sys_clone(fn, child_stack,
|
||
|
|
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_UNTRACED, arg, 0, 0, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
--
|
||
|
|
1.7.12.4
|
||
|
|
|