<commit_before>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "runtime.h"

extern int32	debug;

static int8 spmark[] = "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe";

void
traceback(uint8 *pc, uint8 *sp, void* r15)
{
	int32 spoff;
	int8* spp;
	uint8* callpc;
	int32 counter;
	int32 i;
	int8* name;
	G g;
	Stktop *stktop;

	// store local copy of per-process data block that we can write as we unwind
	mcpy((byte*)&g, (byte*)r15, sizeof(G));

	counter = 0;
	name = "panic";
	for(;;){
		callpc = pc;
		if((uint8*)retfromnewstack == pc) {
			// call site is retfromnewstack(); pop to earlier stack block to get true caller
			stktop = (Stktop*)g.stackbase;
			g.stackbase = stktop->oldbase;
			g.stackguard = stktop->oldguard;
			sp = stktop->oldsp;
			pc = ((uint8**)sp)[1];
			sp += 16;  // two irrelevant calls on stack - morestack, plus the call morestack made
			continue;
		}
		/* find SP offset by stepping back through instructions to SP offset marker */
		while(pc > (uint8*)0x1000+sizeof spmark-1) {
			for(spp = spmark; *spp != '\0' && *pc++ == (uint8)*spp++; )
				;
			if(*spp == '\0'){
				spoff = *pc++;
				spoff += *pc++ << 8;
				spoff += *pc++ << 16;
				name = (int8*)pc;
				sp += spoff + 8;
				break;
			}
		}
		if(counter++ > 100){
			prints("stack trace terminated\n");
			break;
		}
		if((pc = ((uint8**)sp)[-1]) <= (uint8*)0x1000)
			break;
<commit_msg>stop traceback when pc leaves text segment<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "runtime.h"

extern int32	debug;

static int8 spmark[] = "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe";

extern uint8 end;

void
traceback(uint8 *pc, uint8 *sp, void* r15)
{
	int32 spoff;
	int8* spp;
	uint8* callpc;
	int32 counter;
	int32 i;
	int8* name;
	G g;
	Stktop *stktop;

	// store local copy of per-process data block that we can write as we unwind
	mcpy((byte*)&g, (byte*)r15, sizeof(G));

	counter = 0;
	name = "panic";
	for(;;){
		callpc = pc;
		if((uint8*)retfromnewstack == pc) {
			// call site is retfromnewstack(); pop to earlier stack block to get true caller
			stktop = (Stktop*)g.stackbase;
			g.stackbase = stktop->oldbase;
			g.stackguard = stktop->oldguard;
			sp = stktop->oldsp;
			pc = ((uint8**)sp)[1];
			sp += 16;  // two irrelevant calls on stack - morestack, plus the call morestack made
			continue;
		}
		/* find SP offset by stepping back through instructions to SP offset marker */
		while(pc > (uint8*)0x1000+sizeof spmark-1) {
			if(pc >= &end)
				return;
			for(spp = spmark; *spp != '\0' && *pc++ == (uint8)*spp++; )
				;
			if(*spp == '\0'){
				spoff = *pc++;
				spoff += *pc++ << 8;
				spoff += *pc++ << 16;
				name = (int8*)pc;
				sp += spoff + 8;
				break;
			}
		}
		if(counter++ > 100){
			prints("stack trace terminated\n");
			break;
		}
		if((pc = ((uint8**)sp)[-1]) <= (uint8*)0x1000)
			break;

{'fraction_non_alphanumeric': 0.16404715127701375, 'fraction_numerical': 0.040929927963326784, 'mean_word_length': 3.084224598930481, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6476531', 'n_tokens_mistral': 1338, 'n_tokens_neox': 1153, 'n_words': 352}