https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40115
Per Lundberg <perlun at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |perlun at gmail dot com --- Comment #4 from Per Lundberg <perlun at gmail dot com> --- Hi, Andrew - with all due respect, this bug should *not* have been closed. It it still present (at least with gcc 4.7.2). Here is some code (very simplified): new_tss->eip = (u32) &&new_thread_entry; new_tss->cr3 = page_directory_physical_page * SIZE_PAGE; // ... mutex_kernel_signal(&tss_tree_mutex); mutex_kernel_signal(&memory_mutex); new_thread_entry: DEBUG_MESSAGE(DEBUG, "Enabling interrupts"); cpu_interrupts_enable(); Without -O2, the new_tss->eip gets the proper value of the code line right below new_thread_entry. With -O2, I get this (objdump -S output): new_tss->eip = (u32) &&new_thread_entry; 108314: c7 43 20 b1 85 10 00 movl $0x1085b1,0x20(%ebx) Here is where it points to. A number of instructions too early, causing the code to entirely break down. *list = tss_list_node; 1085b1: 89 46 0c mov %eax,0xc(%esi) mutex_kernel_wait(&memory_mutex); mutex_kernel_wait(&tss_tree_mutex); process_info = (process_info_type *) new_tss->process_info; thread_link_list(&process_info->thread_list, new_tss); thread_link(new_tss); 1085b4: 89 1c 24 mov %ebx,(%esp) 1085b7: e8 04 f9 ff ff call 107ec0 <thread_link> number_of_tasks++; 1085bc: a1 60 44 11 00 mov 0x114460,%eax 1085c1: 83 c0 01 add $0x1,%eax 1085c4: a3 60 44 11 00 mov %eax,0x114460 static inline u32 cpu_get_esp(void) { u32 return_value; asm volatile ("movl %%esp, %0" 1085c9: 89 e0 mov %esp,%eax new_tss->esp = cpu_get_esp(); 1085cb: 89 43 38 mov %eax,0x38(%ebx) process_info->number_of_threads++; 1085ce: 83 46 10 01 addl $0x1,0x10(%esi) mutex_kernel_signal(&tss_tree_mutex); 1085d2: c7 04 24 64 3a 11 00 movl $0x113a64,(%esp) 1085d9: e8 f2 21 00 00 call 10a7d0 <mutex_kernel_signal> mutex_kernel_signal(&memory_mutex); 1085de: c7 04 24 0c 44 11 00 movl $0x11440c,(%esp) 1085e5: e8 e6 21 00 00 call 10a7d0 <mutex_kernel_signal> asm ("cli"); } static inline void cpu_interrupts_enable(void) { asm ("sti"); 1085ea: fb sti (the last instruction here is where it *should* have pointed at. :) This used to work with older versions of gcc (last known "good" version is something like 2.95), so obviously something relating to goto labels/O2 has gotten broken during the years. IMHO, this is a clear bug. In my case, I use the address for "jumping" but with indirect jumping (in the new thread being created). Would you say that this is not supported? Does direct jumping (i.e. goto *&&foo) even work at the moment, with -O2? Are there any unit tests or similar for this?