if ((ret & VM_FAULT_WRITE) && !(vma->vm_flags & VM_WRITE))
*flags |= FOLL_COW; // Instead of *flags &= ~FOLL_WRITE;
同时也加入了另一个新的follow_page_mask函数:
/*
* FOLL_FORCE can write to even unwritable pte's, but only
* after we've gone through a COW cycle and they are dirty.
*/
static inline bool can_follow_write_pte(pte_t pte, unsigned int flags)
{
return pte_write(pte) ||
((flags & FOLL_FORCE) && (flags & FOLL_COW) && pte_dirty(pte));
}
static void touch_pmd(struct vm_area_struct *vma, unsigned long addr,
pmd_t *pmd)
{
pmd_t _pmd;
/*
* We should set the dirty bit only for FOLL_WRITE but for now
* the dirty bit in the pmd is meaningless. And if the dirty
* bit will become meaningful and we'll only set it with
* FOLL_WRITE, an atomic set_bit will be required on the pmd to
* set the young bit, instead of the current set_pmd_at.
*/
_pmd = pmd_mkyoung(pmd_mkdirty(*pmd));
if (pmdp_set_access_flags(vma, addr & HPAGE_PMD_MASK,
pmd, _pmd, 1))
update_mmu_cache_pmd(vma, addr, pmd);
}
(gdb) r
Starting program: /opt/firefox/firefox
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x0000555555825487 in eq_demangled_name_entry (a=0x4141414141414141, b=<optimized out>) at symtab.c:697
697 return strcmp (da->mangled, db->mangled) == 0;
(gdb) i s
#0 0x0000555555825487 in eq_demangled_name_entry (a=0x4141414141414141, b=<optimized out>) at symtab.c:697
#1 0x0000555555955203 in htab_find_slot_with_hash (htab=0x555557008e60, element=element@entry=0x7fffffffdb00, hash=4181413748, insert=insert@entry=INSERT) at ./hashtab.c:659
#2 0x0000555555955386 in htab_find_slot (htab=<optimized out>, element=element@entry=0x7fffffffdb00, insert=insert@entry=INSERT) at ./hashtab.c:703
#3 0x00005555558273e5 in symbol_set_names (gsymbol=gsymbol@entry=0x5555595b3778, linkage_name=linkage_name@entry=0x7ffff2ac5254 "_ZN7mozilla3dom16HTMLTableElement11CreateTHeadEv", len=len@entry=48,
copy_name=copy_name@entry=0, objfile=<optimized out>) at symtab.c:818
#4 0x00005555557d186f in minimal_symbol_reader::record_full (this=0x7fffffffdce0, this@entry=0x1768bd6, name=<optimized out>,
name@entry=0x7ffff2ac5254 "_ZN7mozilla3dom16HTMLTableElement11CreateTHeadEv", name_len=<optimized out>, copy_name=copy_name@entry=48, address=24546262, ms_type=ms_type@entry=mst_file_text,
section=13) at minsyms.c:1010
#5 0x00005555556959ec in record_minimal_symbol (reader=..., name=name@entry=0x7ffff2ac5254 "_ZN7mozilla3dom16HTMLTableElement11CreateTHeadEv", name_len=<optimized out>, copy_name=copy_name@entry=false,
address=<optimized out>, address@entry=24546262, ms_type=ms_type@entry=mst_file_text, bfd_section=<optimized out>, objfile=0x555557077860) at elfread.c:209
#6 0x0000555555696ac6 in elf_symtab_read (reader=..., objfile=objfile@entry=0x555557077860, type=type@entry=0, number_of_symbols=number_of_symbols@entry=365691,
symbol_table=symbol_table@entry=0x7ffff6a6d020, copy_names=copy_names@entry=false) at elfread.c:462
#7 0x00005555556970c4 in elf_read_minimal_symbols (symfile_flags=<optimized out>, ei=0x7fffffffdcd0, objfile=0x555557077860) at elfread.c:1084
#8 elf_symfile_read (objfile=0x555557077860, symfile_flags=...) at elfread.c:1194
#9 0x000055555581f559 in read_symbols (objfile=objfile@entry=0x555557077860, add_flags=...) at symfile.c:861
#10 0x000055555581f00b in syms_from_objfile_1 (add_flags=..., addrs=0x555557101b00, objfile=0x555557077860) at symfile.c:1062
#11 syms_from_objfile (add_flags=..., addrs=0x555557101b00, objfile=0x555557077860) at symfile.c:1078
#12 symbol_file_add_with_addrs (abfd=<optimized out>, name=name@entry=0x55555738c1d0 "/opt/firefox/libxul.so", add_flags=..., addrs=addrs@entry=0x555557101b00, flags=..., parent=parent@entry=0x0)
at symfile.c:1177
#13 0x000055555581f63d in symbol_file_add_from_bfd (abfd=<optimized out>, name=name@entry=0x55555738c1d0 "/opt/firefox/libxul.so", add_flags=..., addrs=addrs@entry=0x555557101b00, flags=...,
parent=parent@entry=0x0) at symfile.c:1268
#14 0x000055555580b256 in solib_read_symbols (so=so@entry=0x55555738bfc0, flags=...) at solib.c:712
#15 0x000055555580be9b in solib_add (pattern=pattern@entry=0x0, from_tty=from_tty@entry=0, readsyms=1) at solib.c:1016
#16 0x000055555580c678 in handle_solib_event () at solib.c:1301
#17 0x00005555556f9db4 in bpstat_stop_status (aspace=0x555555ff5670, bp_addr=bp_addr@entry=140737351961185, ptid=..., ws=ws@entry=0x7fffffffe1d0) at breakpoint.c:5712
#18 0x00005555557ad1ef in handle_signal_stop (ecs=0x7fffffffe1b0) at infrun.c:5963
#19 0x00005555557aec8a in handle_inferior_event_1 (ecs=0x7fffffffe1b0) at infrun.c:5392
#20 handle_inferior_event (ecs=ecs@entry=0x7fffffffe1b0) at infrun.c:5427
#21 0x00005555557afd57 in fetch_inferior_event (client_data=<optimized out>) at infrun.c:3932
#22 0x000055555576ade5 in gdb_wait_for_event (block=block@entry=0) at event-loop.c:859
#23 0x000055555576aef7 in gdb_do_one_event () at event-loop.c:322
#24 0x000055555576b095 in gdb_do_one_event () at ./common/common-exceptions.h:221
#25 start_event_loop () at event-loop.c:371
#26 0x00005555557c3938 in captured_command_loop (data=data@entry=0x0) at main.c:325
#27 0x000055555576d243 in catch_errors (func=func@entry=0x5555557c3910 <captured_command_loop(void*)>, func_args=func_args@entry=0x0, errstring=errstring@entry=0x555555a035da "",
mask=mask@entry=RETURN_MASK_ALL) at exceptions.c:236
#28 0x00005555557c49ae in captured_main (data=<optimized out>) at main.c:1150
#29 gdb_main (args=<optimized out>) at main.c:1160
#30 0x00005555555ed628 in main (argc=<optimized out>, argv=<optimized out>) at gdb.c:32
(gdb) list
692 const struct demangled_name_entry *da
693 = (const struct demangled_name_entry *) a;
694 const struct demangled_name_entry *db
695 = (const struct demangled_name_entry *) b;
696
697 return strcmp (da->mangled, db->mangled) == 0;
698 }
699
700 /* Create the hash table used for demangled names. Each hash entry is
701 a pair of strings; one for the mangled name and one for the demangled
(gdb)内存dirty