123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- import {useContext} from 'react';
- import styled from '@emotion/styled';
- import scrollToElement from 'scroll-to-element';
- import {TraceEventDataSectionContext} from 'sentry/components/events/traceEventDataSection';
- import {t} from 'sentry/locale';
- import {DebugMetaActions} from 'sentry/stores/debugMetaStore';
- import space from 'sentry/styles/space';
- import {Frame} from 'sentry/types';
- import DebugImage from '../../debugMeta/debugImage';
- import {combineStatus} from '../../debugMeta/utils';
- import {SymbolicatorStatus} from '../../types';
- import PackageLink from '../packageLink';
- import PackageStatus from '../packageStatus';
- import Symbol from '../symbol';
- import TogglableAddress from '../togglableAddress';
- import {getPlatform} from '../utils';
- import Expander from './expander';
- import LeadHint from './leadHint';
- import Wrapper from './wrapper';
- type Props = React.ComponentProps<typeof Expander> &
- React.ComponentProps<typeof LeadHint> & {
- frame: Frame;
- isUsedForGrouping: boolean;
- image?: React.ComponentProps<typeof DebugImage>['image'];
- includeSystemFrames?: boolean;
- isFrameAfterLastNonApp?: boolean;
- maxLengthOfRelativeAddress?: number;
- onClick?: () => void;
- onMouseDown?: React.MouseEventHandler<HTMLDivElement>;
- prevFrame?: Frame;
- };
- function Native({
- frame,
- isFrameAfterLastNonApp,
- isExpanded,
- isHoverPreviewed,
- image,
- includeSystemFrames,
- maxLengthOfRelativeAddress,
- platform,
- prevFrame,
- isUsedForGrouping,
- nextFrame,
- leadsToApp,
- onMouseDown,
- onClick,
- ...props
- }: Props) {
- const traceEventDataSectionContext = useContext(TraceEventDataSectionContext);
- if (!traceEventDataSectionContext) {
- return null;
- }
- const {instructionAddr, trust, addrMode, symbolicatorStatus} = frame ?? {};
- function packageStatus() {
- // this is the status of image that belongs to this frame
- if (!image) {
- return 'empty';
- }
- const combinedStatus = combineStatus(image.debug_status, image.unwind_status);
- switch (combinedStatus) {
- case 'unused':
- return 'empty';
- case 'found':
- return 'success';
- default:
- return 'error';
- }
- }
- function makeFilter(addr: string): string {
- if (!(!addrMode || addrMode === 'abs') && image) {
- return `${image.debug_id}!${addr}`;
- }
- return addr;
- }
- function scrollToImage(event: React.MouseEvent<HTMLAnchorElement>) {
- event.stopPropagation(); // to prevent collapsing if collapsible
- if (instructionAddr) {
- DebugMetaActions.updateFilter(makeFilter(instructionAddr));
- }
- scrollToElement('#images-loaded');
- }
- const shouldShowLinkToImage =
- !!symbolicatorStatus &&
- symbolicatorStatus !== SymbolicatorStatus.UNKNOWN_IMAGE &&
- !isHoverPreviewed;
- const isInlineFrame =
- prevFrame &&
- getPlatform(frame.platform, platform ?? 'other') ===
- (prevFrame.platform || platform) &&
- instructionAddr === prevFrame.instructionAddr;
- const isFoundByStackScanning = trust === 'scan' || trust === 'cfi-scan';
- return (
- <Wrapper className="title as-table" onMouseDown={onMouseDown} onClick={onClick}>
- <NativeLineContent isFrameAfterLastNonApp={!!isFrameAfterLastNonApp}>
- <PackageInfo>
- <LeadHint
- isExpanded={isExpanded}
- nextFrame={nextFrame}
- leadsToApp={leadsToApp}
- />
- <PackageLink
- includeSystemFrames={!!includeSystemFrames}
- withLeadHint={!(isExpanded || !leadsToApp)}
- packagePath={frame.package}
- onClick={scrollToImage}
- isClickable={shouldShowLinkToImage}
- isHoverPreviewed={isHoverPreviewed}
- >
- {!isHoverPreviewed && (
- <PackageStatus
- status={packageStatus()}
- tooltip={t('Go to Images Loaded')}
- />
- )}
- </PackageLink>
- </PackageInfo>
- {instructionAddr && (
- <TogglableAddress
- address={instructionAddr}
- startingAddress={image ? image.image_addr : null}
- isAbsolute={traceEventDataSectionContext.display.includes(
- 'absolute-addresses'
- )}
- isFoundByStackScanning={isFoundByStackScanning}
- isInlineFrame={!!isInlineFrame}
- relativeAddressMaxlength={maxLengthOfRelativeAddress}
- isHoverPreviewed={isHoverPreviewed}
- />
- )}
- <Symbol
- frame={frame}
- showCompleteFunctionName={traceEventDataSectionContext.display.includes(
- 'verbose-function-names'
- )}
- absoluteFilePaths={traceEventDataSectionContext.display.includes(
- 'absolute-file-paths'
- )}
- isHoverPreviewed={isHoverPreviewed}
- isUsedForGrouping={isUsedForGrouping}
- nativeStackTraceV2
- />
- </NativeLineContent>
- <Expander
- isExpanded={isExpanded}
- isHoverPreviewed={isHoverPreviewed}
- platform={platform}
- {...props}
- />
- </Wrapper>
- );
- }
- export default Native;
- const PackageInfo = styled('span')`
- display: grid;
- grid-template-columns: auto 1fr;
- order: 2;
- align-items: flex-start;
- @media (min-width: ${props => props.theme.breakpoints.small}) {
- order: 0;
- }
- `;
- const NativeLineContent = styled('div')<{isFrameAfterLastNonApp: boolean}>`
- display: grid;
- flex: 1;
- gap: ${space(0.5)};
- grid-template-columns: auto 1fr;
- align-items: center;
- justify-content: flex-start;
- @media (min-width: ${props => props.theme.breakpoints.small}) {
- grid-template-columns:
- ${p => (p.isFrameAfterLastNonApp ? '200px' : '150px')} minmax(117px, auto)
- 1fr;
- }
- @media (min-width: ${props => props.theme.breakpoints.large}) and (max-width: ${props =>
- props.theme.breakpoints.xlarge}) {
- grid-template-columns:
- ${p => (p.isFrameAfterLastNonApp ? '180px' : '140px')} minmax(117px, auto)
- 1fr;
- }
- `;
|