Skip to content

Commit

Permalink
merge revision(s) eab7f46: [Backport #19336]
Browse files Browse the repository at this point in the history
	Return 0 if there is no CFP on the EC yet

	StackProf uses a signal handler to call `rb_profile_frames`.  Signals
	are delivered to threads randomly, and can be delivered after the thread
	has been created but before the CFP has been established on the EC.

	This commit returns early if there is no CFP to use.

	Here is some info from the core files we are seeing.  Here you can see
	the CFP on the current EC is 0x0:

	```
	(gdb) p ruby_current_ec
	$20 = (struct rb_execution_context_struct *) 0x7f3481301b50
	(gdb) p ruby_current_ec->cfp
	$21 = (rb_control_frame_t *) 0x0
	```

	Here is where VM_FRAME_CFRAME_P gets a 0x0 CFP:

	```
	6  VM_FRAME_CFRAME_P (cfp=0x0) at vm_core.h:1350
	7  VM_FRAME_RUBYFRAME_P (cfp=<optimized out>) at vm_core.h:1350
	8  rb_profile_frames (start=0, limit=2048, buff=0x7f3493809590, lines=0x7f349380d590) at vm_backtrace.c:1587
	```

	Down the stack we can see this is happening after thread creation:

	```
	19 0x00007f3495bf9420 in <signal handler called> () at /lib/x86_64-linux-gnu/libpthread.so.0
	20 0x000055d531574e55 in thread_start_func_2 (th=<optimized out>, stack_start=<optimized out>) at thread.c:676
	21 0x000055d531575b31 in thread_start_func_1 (th_ptr=<optimized out>) at thread_pthread.c:1170
	22 0x00007f3495bed609 in start_thread (arg=<optimized out>) at pthread_create.c:477
	23 0x00007f3495b12133 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
	```
	---
	 vm_backtrace.c | 9 +++++++++
	 1 file changed, 9 insertions(+)
  • Loading branch information
nurse committed Jan 18, 2023
1 parent 89cd618 commit 057eff7
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 1 deletion.
2 changes: 1 addition & 1 deletion version.h
Expand Up @@ -11,7 +11,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
#define RUBY_PATCHLEVEL 4
#define RUBY_PATCHLEVEL 5

#include "ruby/version.h"
#include "ruby/internal/abi.h"
Expand Down
9 changes: 9 additions & 0 deletions vm_backtrace.c
Expand Up @@ -1580,6 +1580,15 @@ rb_profile_frames(int start, int limit, VALUE *buff, int *lines)
const rb_control_frame_t *cfp = ec->cfp, *end_cfp = RUBY_VM_END_CONTROL_FRAME(ec);
const rb_callable_method_entry_t *cme;

// If this function is called inside a thread after thread creation, but
// before the CFP has been created, just return 0. This can happen when
// sampling via signals. Threads can be interrupted randomly by the
// signal, including during the time after the thread has been created, but
// before the CFP has been allocated
if (!cfp) {
return 0;
}

// Skip dummy frame; see `rb_ec_partial_backtrace_object` for details
end_cfp = RUBY_VM_NEXT_CONTROL_FRAME(end_cfp);

Expand Down

0 comments on commit 057eff7

Please sign in to comment.