diff options
author | KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> | 2008-10-18 23:27:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-20 11:52:32 -0400 |
commit | e575f111dc0f27044e170580e7de50985ab3e011 (patch) | |
tree | 96021950c36cd6c537a8fc00811f4846767813b8 /include | |
parent | d903ef9f38813e7eb268744a7e579e92f411c83a (diff) |
coredump_filter: add hugepage dumping
Presently hugepage's vma has a VM_RESERVED flag in order not to be
swapped. But a VM_RESERVED vma isn't core dumped because this flag is
often used for some kernel vmas (e.g. vmalloc, sound related).
Thus hugepages are never dumped and it can't be debugged easily. Many
developers want hugepages to be included into core-dump.
However, We can't read generic VM_RESERVED area because this area is often
IO mapping area. then these area reading may change device state. it is
definitly undesiable side-effect.
So adding a hugepage specific bit to the coredump filter is better. It
will be able to hugepage core dumping and doesn't cause any side-effect to
any i/o devices.
In additional, libhugetlb use hugetlb private mapping pages as anonymous
page. Then, hugepage private mapping pages should be core dumped by
default.
Then, /proc/[pid]/core_dump_filter has two new bits.
- bit 5 mean hugetlb private mapping pages are dumped or not. (default: yes)
- bit 6 mean hugetlb shared mapping pages are dumped or not. (default: no)
I tested by following method.
% ulimit -c unlimited
% ./crash_hugepage 50
% ./crash_hugepage 50 -p
% ls -lh
% gdb ./crash_hugepage core
%
% echo 0x43 > /proc/self/coredump_filter
% ./crash_hugepage 50
% ./crash_hugepage 50 -p
% ls -lh
% gdb ./crash_hugepage core
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include "hugetlbfs.h"
int main(int argc, char** argv){
char* p;
int ch;
int mmap_flags = MAP_SHARED;
int fd;
int nr_pages;
while((ch = getopt(argc, argv, "p")) != -1) {
switch (ch) {
case 'p':
mmap_flags &= ~MAP_SHARED;
mmap_flags |= MAP_PRIVATE;
break;
default:
/* nothing*/
break;
}
}
argc -= optind;
argv += optind;
if (argc == 0){
printf("need # of pages\n");
exit(1);
}
nr_pages = atoi(argv[0]);
if (nr_pages < 2) {
printf("nr_pages must >2\n");
exit(1);
}
fd = hugetlbfs_unlinked_fd();
p = mmap(NULL, nr_pages * gethugepagesize(),
PROT_READ|PROT_WRITE, mmap_flags, fd, 0);
sleep(2);
*(p + gethugepagesize()) = 1; /* COW */
sleep(2);
/* crash! */
*(int*)0 = 1;
return 0;
}
Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Reviewed-by: Kawai Hidehiro <hidehiro.kawai.ez@hitachi.com>
Cc: Hugh Dickins <hugh@veritas.com>
Cc: William Irwin <wli@holomorphy.com>
Cc: Adam Litke <agl@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/sched.h | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index c226c7b82946..017cc914ef1f 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -403,12 +403,15 @@ extern int get_dumpable(struct mm_struct *mm); | |||
403 | #define MMF_DUMP_MAPPED_PRIVATE 4 | 403 | #define MMF_DUMP_MAPPED_PRIVATE 4 |
404 | #define MMF_DUMP_MAPPED_SHARED 5 | 404 | #define MMF_DUMP_MAPPED_SHARED 5 |
405 | #define MMF_DUMP_ELF_HEADERS 6 | 405 | #define MMF_DUMP_ELF_HEADERS 6 |
406 | #define MMF_DUMP_HUGETLB_PRIVATE 7 | ||
407 | #define MMF_DUMP_HUGETLB_SHARED 8 | ||
406 | #define MMF_DUMP_FILTER_SHIFT MMF_DUMPABLE_BITS | 408 | #define MMF_DUMP_FILTER_SHIFT MMF_DUMPABLE_BITS |
407 | #define MMF_DUMP_FILTER_BITS 5 | 409 | #define MMF_DUMP_FILTER_BITS 7 |
408 | #define MMF_DUMP_FILTER_MASK \ | 410 | #define MMF_DUMP_FILTER_MASK \ |
409 | (((1 << MMF_DUMP_FILTER_BITS) - 1) << MMF_DUMP_FILTER_SHIFT) | 411 | (((1 << MMF_DUMP_FILTER_BITS) - 1) << MMF_DUMP_FILTER_SHIFT) |
410 | #define MMF_DUMP_FILTER_DEFAULT \ | 412 | #define MMF_DUMP_FILTER_DEFAULT \ |
411 | ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED)) | 413 | ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED) |\ |
414 | (1 << MMF_DUMP_HUGETLB_PRIVATE)) | ||
412 | 415 | ||
413 | struct sighand_struct { | 416 | struct sighand_struct { |
414 | atomic_t count; | 417 | atomic_t count; |