`,c.children[0].getAttribute("foo")):(c.innerHTML=e,c.textContent)},isBuiltInComponent:e=>"Transition"===e||"transition"===e?ay:"TransitionGroup"===e||"transition-group"===e?av:void 0,getNamespace(e,t,n){let r=t?t.ns:n;if(t&&2===r){if("annotation-xml"===t.tag){if("svg"===e)return 1;t.props.some(e=>6===e.type&&"encoding"===e.name&&null!=e.value&&("text/html"===e.value.content||"application/xhtml+xml"===e.value.content))&&(r=0)}else/^m(?:[ions]|text)$/.test(t.tag)&&"mglyph"!==e&&"malignmark"!==e&&(r=0)}else t&&1===r&&("foreignObject"===t.tag||"desc"===t.tag||"title"===t.tag)&&(r=0);if(0===r){if("svg"===e)return 1;if("math"===e)return 2}return r}},a_=(e,t)=>sw(JSON.stringify(er(e)),!1,t,3),aS=u("passive,once,capture"),ax=u("stop,prevent,self,ctrl,shift,alt,meta,exact,middle"),aC=u("left,right"),ak=u("onkeyup,onkeydown,onkeypress",!0),aT=(e,t,n,r)=>{let i=[],l=[],s=[];for(let n=0;n
sj(e)&&"onclick"===e.content.toLowerCase()?sw(t,!0):4!==e.type?sE(["(",e,`) === "onClick" ? "${t}" : (`,e,")"]):e,aE=(e,t)=>{1===e.type&&0===e.tagType&&("script"===e.tag||"style"===e.tag)&&t.removeNode()},aA=[e=>{1===e.type&&e.props.forEach((t,n)=>{6===t.type&&"style"===t.name&&t.value&&(e.props[n]={type:7,name:"bind",arg:sw("style",!0,t.loc),exp:a_(t.value.content,t.loc),modifiers:[],loc:t.loc})})}],aN={cloak:()=>({props:[]}),html:(e,t,n)=>{let{exp:r,loc:i}=e;return r||n.onError(sU(53,i)),t.children.length&&(n.onError(sU(54,i)),t.children.length=0),{props:[sT(sw("innerHTML",!0,i),r||sw("",!0))]}},text:(e,t,n)=>{let{exp:r,loc:i}=e;return r||n.onError(sU(55,i)),t.children.length&&(n.onError(sU(56,i)),t.children.length=0),{props:[sT(sw("textContent",!0),r?oN(r,n)>0?r:sA(n.helperString(sn),[r],i):sw("",!0))]}},model:(e,t,n)=>{let r=al(e,t,n);if(!r.props.length||1===t.tagType)return r;e.arg&&n.onError(sU(58,e.arg.loc));let{tag:i}=t,l=n.isCustomElement(i);if("input"===i||"textarea"===i||"select"===i||l){let s=ad,o=!1;if("input"===i||l){let r=sQ(t,"type");if(r){if(7===r.type)s=ah;else if(r.value)switch(r.value.content){case"radio":s=ac;break;case"checkbox":s=au;break;case"file":o=!0,n.onError(sU(59,e.loc))}}else t.props.some(e=>7===e.type&&"bind"===e.name&&(!e.arg||4!==e.arg.type||!e.arg.isStatic))&&(s=ah)}else"select"===i&&(s=ap);o||(r.needRuntime=n.helper(s))}else n.onError(sU(57,e.loc));return r.props=r.props.filter(e=>!(4===e.key.type&&"modelValue"===e.key.content)),r},on:(e,t,n)=>at(e,t,n,t=>{let{modifiers:r}=e;if(!r.length)return t;let{key:i,value:l}=t.props[0],{keyModifiers:s,nonKeyModifiers:o,eventOptionModifiers:a}=aT(i,r,n,e.loc);if(o.includes("right")&&(i=aw(i,"onContextmenu")),o.includes("middle")&&(i=aw(i,"onMouseup")),o.length&&(l=sA(n.helper(af),[l,JSON.stringify(o)])),s.length&&(!sj(i)||ak(i.content))&&(l=sA(n.helper(am),[l,JSON.stringify(s)])),a.length){let e=a.map(q).join("");i=sj(i)?sw(`${i.content}${e}`,!0):sE(["(",i,`) + "${e}"`])}return{props:[sT(i,l)]}}),show:(e,t,n)=>{let{exp:r,loc:i}=e;return!r&&n.onError(sU(61,i)),{props:[],needRuntime:n.helper(ag)}}},aI=new WeakMap;function aR(e,t){let n;if(!A(e)){if(!e.nodeType)return h;e=e.innerHTML}let r=e,i=((n=aI.get(null!=t?t:d))||(n=Object.create(null),aI.set(null!=t?t:d,n)),n),l=i[r];if(l)return l;if("#"===e[0]){let t=document.querySelector(e);e=t?t.innerHTML:""}let s=y({hoistStatic:!0,onError:void 0,onWarn:h},t);s.isCustomElement||"undefined"==typeof customElements||(s.isCustomElement=e=>!!customElements.get(e));let{code:o}=function(e,t={}){return function(e,t={}){let n=t.onError||sB,r="module"===t.mode;!0===t.prefixIdentifiers?n(sU(47)):r&&n(sU(48)),t.cacheHandlers&&n(sU(49)),t.scopeId&&!r&&n(sU(50));let i=y({},t,{prefixIdentifiers:!1}),l=A(e)?function(e,t){if(od.reset(),on=null,or=null,oi="",ol=-1,os=-1,ou.length=0,ot=e,s7=y({},s9),t){let e;for(e in t)null!=t[e]&&(s7[e]=t[e])}od.mode="html"===s7.parseMode?1:"sfc"===s7.parseMode?2:0,od.inXML=1===s7.ns||2===s7.ns;let n=t&&t.delimiters;n&&(od.delimiterOpen=sF(n[0]),od.delimiterClose=sF(n[1]));let r=oe=function(e,t=""){return{type:0,source:t,children:e,helpers:new Set,components:[],directives:[],hoists:[],imports:[],cached:0,temps:0,codegenNode:void 0,loc:sS}}([],e);return od.parse(ot),r.loc=ok(0,e.length),r.children=oS(r.children),oe=null,r}(e,i):e,[s,o]=[[ai,oq,aa,oQ,o7,o4,o1,an],{on:at,bind:oG,model:al}];return!function(e,t){let n=function(e,{filename:t="",prefixIdentifiers:n=!1,hoistStatic:r=!1,hmr:i=!1,cacheHandlers:l=!1,nodeTransforms:s=[],directiveTransforms:o={},transformHoist:a=null,isBuiltInComponent:c=h,isCustomElement:u=h,expressionPlugins:p=[],scopeId:f=null,slotted:m=!0,ssr:g=!1,inSSR:y=!1,ssrCssVars:b="",bindingMetadata:_=d,inline:S=!1,isTS:x=!1,onError:C=sB,onWarn:k=sD,compatConfig:T}){let w=t.replace(/\?.*$/,"").match(/([^/\\]+)\.\w+$/),E={filename:t,selfName:w&&q(U(w[1])),prefixIdentifiers:n,hoistStatic:r,hmr:i,cacheHandlers:l,nodeTransforms:s,directiveTransforms:o,transformHoist:a,isBuiltInComponent:c,isCustomElement:u,expressionPlugins:p,scopeId:f,slotted:m,ssr:g,inSSR:y,ssrCssVars:b,bindingMetadata:_,inline:S,isTS:x,onError:C,onWarn:k,compatConfig:T,root:e,helpers:new Map,components:new Set,directives:new Set,hoists:[],imports:[],constantCache:new WeakMap,temps:0,cached:0,identifiers:Object.create(null),scopes:{vFor:0,vSlot:0,vPre:0,vOnce:0},parent:null,grandParent:null,currentNode:e,childIndex:0,inVOnce:!1,helper(e){let t=E.helpers.get(e)||0;return E.helpers.set(e,t+1),e},removeHelper(e){let t=E.helpers.get(e);if(t){let n=t-1;n?E.helpers.set(e,n):E.helpers.delete(e)}},helperString:e=>`_${s_[E.helper(e)]}`,replaceNode(e){E.parent.children[E.childIndex]=E.currentNode=e},removeNode(e){let t=E.parent.children,n=e?t.indexOf(e):E.currentNode?E.childIndex:-1;e&&e!==E.currentNode?E.childIndex>n&&(E.childIndex--,E.onNodeRemoved()):(E.currentNode=null,E.onNodeRemoved()),E.parent.children.splice(n,1)},onNodeRemoved:h,addIdentifiers(e){},removeIdentifiers(e){},hoist(e){A(e)&&(e=sw(e)),E.hoists.push(e);let t=sw(`_hoisted_${E.hoists.length}`,!1,e.loc,2);return t.hoisted=e,t},cache:(e,t=!1)=>(function(e,t,n=!1){return{type:20,index:e,value:t,isVNode:n,loc:sS}})(E.cached++,e,t)};return E}(e,t);o$(e,n),t.hoistStatic&&function e(t,n,r=!1){let{children:i}=t,l=i.length,s=0;for(let t=0;t0){if(e>=2){l.codegenNode.patchFlag="-1",l.codegenNode=n.hoist(l.codegenNode),s++;continue}}else{let e=l.codegenNode;if(13===e.type){let t=oL(e);if((!t||512===t||1===t)&&oR(l,n)>=2){let t=oO(l);t&&(e.props=n.hoist(t))}e.dynamicProps&&(e.dynamicProps=n.hoist(e.dynamicProps))}}}if(1===l.type){let t=1===l.tagType;t&&n.scopes.vSlot++,e(l,n),t&&n.scopes.vSlot--}else if(11===l.type)e(l,n,1===l.children.length);else if(9===l.type)for(let t=0;t1&&(e.codegenNode=sx(t,n(lW),void 0,e.children,"64",void 0,void 0,!0,void 0,!1))}(e,n),e.helpers=new Set([...n.helpers.keys()]),e.components=[...n.components],e.directives=[...n.directives],e.imports=n.imports,e.hoists=n.hoists,e.temps=n.temps,e.cached=n.cached,e.transformed=!0}(l,y({},i,{nodeTransforms:[...s,...t.nodeTransforms||[]],directiveTransforms:y({},o,t.directiveTransforms||{})})),function(e,t={}){let n=function(e,{mode:t="function",prefixIdentifiers:n="module"===t,sourceMap:r=!1,filename:i="template.vue.html",scopeId:l=null,optimizeImports:s=!1,runtimeGlobalName:o="Vue",runtimeModuleName:a="vue",ssrRuntimeModuleName:c="vue/server-renderer",ssr:u=!1,isTS:d=!1,inSSR:p=!1}){let h={mode:t,prefixIdentifiers:n,sourceMap:r,filename:i,scopeId:l,optimizeImports:s,runtimeGlobalName:o,runtimeModuleName:a,ssrRuntimeModuleName:c,ssr:u,isTS:d,inSSR:p,source:e.source,code:"",column:1,line:1,offset:0,indentLevel:0,pure:!1,map:void 0,helper:e=>`_${s_[e]}`,push(e,t=-2,n){h.code+=e},indent(){f(++h.indentLevel)},deindent(e=!1){e?--h.indentLevel:f(--h.indentLevel)},newline(){f(h.indentLevel)}};function f(e){h.push("\n"+" ".repeat(e),0)}return h}(e,t);t.onContextCreated&&t.onContextCreated(n);let{mode:r,push:i,prefixIdentifiers:l,indent:s,deindent:o,newline:a,scopeId:c,ssr:u}=n,d=Array.from(e.helpers),p=d.length>0,h=!l&&"module"!==r;(function(e,t){let{ssr:n,prefixIdentifiers:r,push:i,newline:l,runtimeModuleName:s,runtimeGlobalName:o,ssrRuntimeModuleName:a}=t,c=Array.from(e.helpers);if(c.length>0&&(i(`const _Vue = ${o}
+`,-1),e.hoists.length)){let e=[lY,l0,l1,l2,l3].filter(e=>c.includes(e)).map(oF).join(", ");i(`const { ${e} } = _Vue
+`,-1)}(function(e,t){if(!e.length)return;t.pure=!0;let{push:n,newline:r,helper:i,scopeId:l,mode:s}=t;r();for(let i=0;i0)&&a()),e.directives.length&&(oV(e.directives,"directive",n),e.temps>0&&a()),e.temps>0){i("let ");for(let t=0;t0?", ":""}_temp${t}`)}return(e.components.length||e.directives.length||e.temps)&&(i(`
+`,0),a()),u||i("return "),e.codegenNode?oU(e.codegenNode,n):i("null"),h&&(o(),i("}")),o(),i("}"),{ast:e,code:n.code,preamble:"",map:n.map?n.map.toJSON():void 0}}(l,i)}(e,y({},ab,t,{nodeTransforms:[aE,...aA,...t.nodeTransforms||[]],directiveTransforms:y({},aN,t.directiveTransforms||{}),transformHoist:null}))}(e,s),a=Function(o)();return a._rc=!0,i[r]=a}return iw(aR),e.BaseTransition=rD,e.BaseTransitionPropsValidators=rV,e.Comment=r2,e.DeprecationTypes=null,e.EffectScope=eg,e.ErrorCodes={SETUP_FUNCTION:0,0:"SETUP_FUNCTION",RENDER_FUNCTION:1,1:"RENDER_FUNCTION",WATCH_GETTER:2,2:"WATCH_GETTER",WATCH_CALLBACK:3,3:"WATCH_CALLBACK",WATCH_CLEANUP:4,4:"WATCH_CLEANUP",NATIVE_EVENT_HANDLER:5,5:"NATIVE_EVENT_HANDLER",COMPONENT_EVENT_HANDLER:6,6:"COMPONENT_EVENT_HANDLER",VNODE_HOOK:7,7:"VNODE_HOOK",DIRECTIVE_HOOK:8,8:"DIRECTIVE_HOOK",TRANSITION_HOOK:9,9:"TRANSITION_HOOK",APP_ERROR_HANDLER:10,10:"APP_ERROR_HANDLER",APP_WARN_HANDLER:11,11:"APP_WARN_HANDLER",FUNCTION_REF:12,12:"FUNCTION_REF",ASYNC_COMPONENT_LOADER:13,13:"ASYNC_COMPONENT_LOADER",SCHEDULER:14,14:"SCHEDULER"},e.ErrorTypeStrings=null,e.Fragment=r0,e.KeepAlive={name:"KeepAlive",__isKeepAlive:!0,props:{include:[String,RegExp,Array],exclude:[String,RegExp,Array],max:[String,Number]},setup(e,{slots:t}){let n=i_(),r=n.ctx,i=new Map,l=new Set,s=null,o=n.suspense,{renderer:{p:a,m:c,um:u,o:{createElement:d}}}=r,p=d("div");function h(e){rO(e),u(e,n,o,!0)}function f(e){i.forEach((t,n)=>{let r=iR(t.type);!r||e&&e(r)||m(n)})}function m(e){let t=i.get(e);s&&ir(t,s)?s&&rO(s):h(t),i.delete(e),l.delete(e)}r.activate=(e,t,n,r,i)=>{let l=e.component;c(e,t,n,0,o),a(l.vnode,e,t,n,l,o,r,e.slotScopeIds,i),rd(()=>{l.isDeactivated=!1,l.a&&z(l.a);let t=e.props&&e.props.onVnodeMounted;t&&ig(t,l.parent,e)},o)},r.deactivate=e=>{let t=e.component;rv(t.m),rv(t.a),c(e,p,null,1,o),rd(()=>{t.da&&z(t.da);let n=e.props&&e.props.onVnodeUnmounted;n&&ig(n,t.parent,e),t.isDeactivated=!0},o)},rC(()=>[e.include,e.exclude],([e,t])=>{e&&f(t=>rA(e,t)),t&&f(e=>!rA(t,e))},{flush:"post",deep:!0});let g=null,y=()=>{null!=g&&(no(n.subTree.type)?rd(()=>{i.set(g,rL(n.subTree))},n.subTree.suspense):i.set(g,rL(n.subTree)))};return ny(y),nb(y),n_(()=>{i.forEach(e=>{let{subTree:t,suspense:r}=n,i=rL(t);if(e.type===i.type&&e.key===i.key){rO(i);let e=i.component.da;e&&rd(e,r);return}h(e)})}),()=>{if(g=null,!t.default)return null;let n=t.default(),r=n[0];if(n.length>1)return s=null,n;if(!it(r)||!(4&r.shapeFlag)&&!(128&r.shapeFlag))return s=null,r;let o=rL(r),a=o.type,c=iR(nA(o)?o.type.__asyncResolved||{}:a),{include:u,exclude:d,max:p}=e;if(u&&(!c||!rA(u,c))||d&&c&&rA(d,c))return s=o,r;let h=null==o.key?a:o.key,f=i.get(h);return o.el&&(o=ic(o),128&r.shapeFlag&&(r.ssContent=o)),g=h,f?(o.el=f.el,o.component=f.component,o.transition&&rW(o,o.transition),o.shapeFlag|=512,l.delete(h),l.add(h)):(l.add(h),p&&l.size>parseInt(p,10)&&m(l.values().next().value)),o.shapeFlag|=256,s=o,no(r.type)?r:o}}},e.ReactiveEffect=ev,e.Static=r3,e.Suspense={name:"Suspense",__isSuspense:!0,process(e,t,n,r,i,l,s,o,a,c){if(null==e)(function(e,t,n,r,i,l,s,o,a){let{p:c,o:{createElement:u}}=a,d=u("div"),p=e.suspense=nu(e,i,r,t,d,n,l,s,o,a);c(null,p.pendingBranch=e.ssContent,d,null,r,p,l,s),p.deps>0?(nc(e,"onPending"),nc(e,"onFallback"),c(null,e.ssFallback,t,n,r,null,l,s),nh(p,e.ssFallback)):p.resolve(!1,!0)})(t,n,r,i,l,s,o,a,c);else{if(l&&l.deps>0&&!e.suspense.isInFallback){t.suspense=e.suspense,t.suspense.vnode=t,t.el=e.el;return}(function(e,t,n,r,i,l,s,o,{p:a,um:c,o:{createElement:u}}){let d=t.suspense=e.suspense;d.vnode=t,t.el=e.el;let p=t.ssContent,h=t.ssFallback,{activeBranch:f,pendingBranch:m,isInFallback:g,isHydrating:y}=d;if(m)d.pendingBranch=p,ir(p,m)?(a(m,p,d.hiddenContainer,null,i,d,l,s,o),d.deps<=0?d.resolve():g&&!y&&(a(f,h,n,r,i,null,l,s,o),nh(d,h))):(d.pendingId=na++,y?(d.isHydrating=!1,d.activeBranch=m):c(m,i,d),d.deps=0,d.effects.length=0,d.hiddenContainer=u("div"),g?(a(null,p,d.hiddenContainer,null,i,d,l,s,o),d.deps<=0?d.resolve():(a(f,h,n,r,i,null,l,s,o),nh(d,h))):f&&ir(p,f)?(a(f,p,n,r,i,d,l,s,o),d.resolve(!0)):(a(null,p,d.hiddenContainer,null,i,d,l,s,o),d.deps<=0&&d.resolve()));else if(f&&ir(p,f))a(f,p,n,r,i,d,l,s,o),nh(d,p);else if(nc(t,"onPending"),d.pendingBranch=p,512&p.shapeFlag?d.pendingId=p.component.suspenseId:d.pendingId=na++,a(null,p,d.hiddenContainer,null,i,d,l,s,o),d.deps<=0)d.resolve();else{let{timeout:e,pendingId:t}=d;e>0?setTimeout(()=>{d.pendingId===t&&d.fallback(h)},e):0===e&&d.fallback(h)}})(e,t,n,r,i,s,o,a,c)}},hydrate:function(e,t,n,r,i,l,s,o,a){let c=t.suspense=nu(t,r,n,e.parentNode,document.createElement("div"),null,i,l,s,o,!0),u=a(e,c.pendingBranch=t.ssContent,n,c,l,s);return 0===c.deps&&c.resolve(!1,!0),u},normalize:function(e){let{shapeFlag:t,children:n}=e,r=32&t;e.ssContent=nd(r?n.default:n),e.ssFallback=r?nd(n.fallback):io(r2)}},e.Teleport={name:"Teleport",__isTeleport:!0,process(e,t,n,r,i,l,s,o,a,c){let{mc:u,pc:d,pbc:p,o:{insert:h,querySelector:f,createText:m,createComment:g}}=c,y=rG(t.props),{shapeFlag:b,children:_,dynamicChildren:S}=t;if(null==e){let e=t.el=m(""),c=t.anchor=m("");h(e,n,r),h(c,n,r);let d=t.target=rQ(t.props,f),p=t.targetAnchor=m("");d&&(h(p,d),"svg"===s||rJ(d)?s="svg":("mathml"===s||rX(d))&&(s="mathml"));let g=(e,t)=>{16&b&&u(_,e,t,i,l,s,o,a)};y?g(n,c):d&&g(d,p)}else{t.el=e.el;let r=t.anchor=e.anchor,u=t.target=e.target,h=t.targetAnchor=e.targetAnchor,m=rG(e.props),g=m?n:u;if("svg"===s||rJ(u)?s="svg":("mathml"===s||rX(u))&&(s="mathml"),S?(p(e.dynamicChildren,S,g,i,l,s,o),ry(e,t,!0)):a||d(e,t,g,m?r:h,i,l,s,o,!1),y)m?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):rZ(t,n,r,c,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){let e=t.target=rQ(t.props,f);e&&rZ(t,e,null,c,0)}else m&&rZ(t,u,h,c,1)}rY(t)},remove(e,t,n,{um:r,o:{remove:i}},l){let{shapeFlag:s,children:o,anchor:a,targetAnchor:c,target:u,props:d}=e;if(u&&i(c),l&&i(a),16&s){let e=l||!rG(d);for(let i=0;i{let t=(a||(a=rh(lV))).createApp(...e),{mount:n}=t;return t.mount=e=>{let r=lq(e);if(!r)return;let i=t._component;E(i)||i.render||i.template||(i.template=r.innerHTML),r.innerHTML="";let l=n(r,!1,lH(r));return r instanceof Element&&(r.removeAttribute("v-cloak"),r.setAttribute("data-v-app","")),l},t},e.createBlock=ie,e.createCommentVNode=function(e="",t=!1){return t?(r8(),ie(r2,null,e)):io(r2,null,e)},e.createElementBlock=function(e,t,n,r,i,l){return r7(is(e,t,n,r,i,l,!0))},e.createElementVNode=is,e.createHydrationRenderer=rp,e.createPropsRestProxy=function(e,t){let n={};for(let r in e)t.includes(r)||Object.defineProperty(n,r,{enumerable:!0,get:()=>e[r]});return n},e.createRenderer=function(e){return rh(e)},e.createSSRApp=(...e)=>{let t=lD().createApp(...e),{mount:n}=t;return t.mount=e=>{let t=lq(e);if(t)return n(t,!0,lH(t))},t},e.createSlots=function(e,t){for(let n=0;n{let t=r.fn(...e);return t&&(t.key=r.key),t}:r.fn)}return e},e.createStaticVNode=function(e,t){let n=io(r3,null,e);return n.staticCount=t,n},e.createTextVNode=iu,e.createVNode=io,e.customRef=tO,e.defineAsyncComponent=/*! #__NO_SIDE_EFFECTS__ */function(e){let t;E(e)&&(e={loader:e});let{loader:n,loadingComponent:r,errorComponent:i,delay:l=200,timeout:s,suspensible:o=!0,onError:a}=e,c=null,u=0,d=()=>(u++,c=null,p()),p=()=>{let e;return c||(e=c=n().catch(e=>{if(e=e instanceof Error?e:Error(String(e)),a)return new Promise((t,n)=>{a(e,()=>t(d()),()=>n(e),u+1)});throw e}).then(n=>e!==c&&c?c:(n&&(n.__esModule||"Module"===n[Symbol.toStringTag])&&(n=n.default),t=n,n)))};return nE({name:"AsyncComponentWrapper",__asyncLoader:p,get __asyncResolved(){return t},setup(){let e=ib;if(t)return()=>nN(t,e);let n=t=>{c=null,tV(t,e,13,!i)};if(o&&e.suspense)return p().then(t=>()=>nN(t,e)).catch(e=>(n(e),()=>i?io(i,{error:e}):null));let a=tT(!1),u=tT(),d=tT(!!l);return l&&setTimeout(()=>{d.value=!1},l),null!=s&&setTimeout(()=>{if(!a.value&&!u.value){let e=Error(`Async component timed out after ${s}ms.`);n(e),u.value=e}},s),p().then(()=>{a.value=!0,e.parent&&rE(e.parent.vnode)&&(e.parent.effect.dirty=!0,tJ(e.parent.update))}).catch(e=>{n(e),u.value=e}),()=>a.value&&t?nN(t,e):u.value&&i?io(i,{error:u.value}):r&&!d.value?io(r):void 0}})},e.defineComponent=nE,e.defineCustomElement=ld,e.defineEmits=function(){return null},e.defineExpose=function(e){},e.defineModel=function(){},e.defineOptions=function(e){},e.defineProps=function(){return null},e.defineSSRCustomElement=(e,t)=>ld(e,t,lj),e.defineSlots=function(){return null},e.devtools=void 0,e.effect=function(e,t){e.effect instanceof ev&&(e=e.effect.fn);let n=new ev(e,h,()=>{n.dirty&&n.run()});t&&(y(n,t),t.scope&&ey(n,t.scope)),t&&t.lazy||n.run();let r=n.run.bind(n);return r.effect=n,r},e.effectScope=function(e){return new eg(e)},e.getCurrentInstance=i_,e.getCurrentScope=function(){return n},e.getTransitionRawChildren=rK,e.guardReactiveProps=ia,e.h=iL,e.handleError=tV,e.hasInjectionContext=function(){return!!(ib||t6||nJ)},e.hydrate=lj,e.initCustomFormatter=function(){},e.initDirectivesForSSR=h,e.inject=nQ,e.isMemoSame=i$,e.isProxy=tg,e.isReactive=th,e.isReadonly=tf,e.isRef=tk,e.isRuntimeOnly=()=>!s,e.isShallow=tm,e.isVNode=it,e.markRaw=tv,e.mergeDefaults=function(e,t){let n=nP(e);for(let e in t){if(e.startsWith("__skip"))continue;let r=n[e];r?x(r)||E(r)?r=n[e]={type:r,default:t[e]}:r.default=t[e]:null===r&&(r=n[e]={default:t[e]}),r&&t[`__skip_${e}`]&&(r.skipFactory=!0)}return n},e.mergeModels=function(e,t){return e&&t?x(e)&&x(t)?e.concat(t):y({},nP(e),nP(t)):e||t},e.mergeProps=im,e.nextTick=tG,e.normalizeClass=ei,e.normalizeProps=function(e){if(!e)return null;let{class:t,style:n}=e;return t&&!A(t)&&(e.class=ei(t)),n&&(e.style=Y(n)),e},e.normalizeStyle=Y,e.onActivated=rN,e.onBeforeMount=ng,e.onBeforeUnmount=n_,e.onBeforeUpdate=nv,e.onDeactivated=rI,e.onErrorCaptured=nT,e.onMounted=ny,e.onRenderTracked=nk,e.onRenderTriggered=nC,e.onScopeDispose=function(e){n&&n.cleanups.push(e)},e.onServerPrefetch=nx,e.onUnmounted=nS,e.onUpdated=nb,e.openBlock=r8,e.popScopeId=function(){t4=null},e.provide=nX,e.proxyRefs=tI,e.pushScopeId=function(e){t4=e},e.queuePostFlushCb=tQ,e.reactive=tc,e.readonly=td,e.ref=tT,e.registerRuntimeCompiler=iw,e.render=lU,e.renderList=function(e,t,n,r){let i;let l=n&&n[r];if(x(e)||A(e)){i=Array(e.length);for(let n=0,r=e.length;nt(e,n,void 0,l&&l[n]));else{let n=Object.keys(e);i=Array(n.length);for(let r=0,s=n.length;r!it(t)||!!(t.type!==r2&&(t.type!==r0||e(t.children))))?t:null}(l(n)),o=ie(r0,{key:n.key||s&&s.key||`_${t}`},s||(r?r():[]),s&&1===e._?64:-2);return!i&&o.scopeId&&(o.slotScopeIds=[o.scopeId+"-s"]),l&&l._c&&(l._d=!0),o},e.resolveComponent=function(e,t){return nl(nr,e,!0,t)||e},e.resolveDirective=function(e){return nl("directives",e)},e.resolveDynamicComponent=function(e){return A(e)?nl(nr,e,!1)||e:e||ni},e.resolveFilter=null,e.resolveTransitionHooks=rj,e.setBlockTracking=function(e){r9+=e},e.setDevtoolsHook=h,e.setTransitionHooks=rW,e.shallowReactive=tu,e.shallowReadonly=function(e){return tp(e,!0,ez,ti,ta)},e.shallowRef=function(e){return tw(e,!0)},e.ssrContextKey=rb,e.ssrUtils=null,e.stop=function(e){e.effect.stop()},e.toDisplayString=eh,e.toHandlerKey=W,e.toHandlers=function(e,t){let n={};for(let r in e)n[t&&/[A-Z]/.test(r)?`on:${r}`:W(r)]=e[r];return n},e.toRaw=ty,e.toRef=function(e,t,n){return tk(e)?e:E(e)?new t$(e):I(e)&&arguments.length>1?tM(e,t,n):tT(e)},e.toRefs=function(e){let t=x(e)?Array(e.length):{};for(let n in e)t[n]=tM(e,n);return t},e.toValue=function(e){return E(e)?e():tA(e)},e.transformVNodeArgs=function(e){},e.triggerRef=function(e){tC(e,4)},e.unref=tA,e.useAttrs=function(){return nM().attrs},e.useCssModule=function(e="$style"){return d},e.useCssVars=function(e){let t=i_();if(!t)return;let n=t.ut=(n=e(t.proxy))=>{Array.from(document.querySelectorAll(`[data-v-owner="${t.uid}"]`)).forEach(e=>i8(e,n))},r=()=>{let r=e(t.proxy);(function e(t,n){if(128&t.shapeFlag){let r=t.suspense;t=r.activeBranch,r.pendingBranch&&!r.isHydrating&&r.effects.push(()=>{e(r.activeBranch,n)})}for(;t.component;)t=t.component.subTree;if(1&t.shapeFlag&&t.el)i8(t.el,n);else if(t.type===r0)t.children.forEach(t=>e(t,n));else if(t.type===r3){let{el:e,anchor:r}=t;for(;e&&(i8(e,n),e!==r);)e=e.nextSibling}})(t.subTree,r),n(r)};ny(()=>{r_(r);let e=new MutationObserver(r);e.observe(t.subTree.el.parentNode,{childList:!0}),nS(()=>e.disconnect())})},e.useModel=function(e,t,n=d){let r=i_(),i=U(t),l=H(t),s=tO((s,o)=>{let a;return rS(()=>{let n=e[t];K(a,n)&&(a=n,o())}),{get:()=>(s(),n.get?n.get(a):a),set(e){let s=r.vnode.props;!(s&&(t in s||i in s||l in s)&&(`onUpdate:${t}` in s||`onUpdate:${i}` in s||`onUpdate:${l}` in s))&&K(e,a)&&(a=e,o()),r.emit(`update:${t}`,n.set?n.set(e):e)}}}),o="modelValue"===t?"modelModifiers":`${t}Modifiers`;return s[Symbol.iterator]=()=>{let t=0;return{next:()=>t<2?{value:t++?e[o]||{}:s,done:!1}:{done:!0}}},s},e.useSSRContext=()=>{},e.useSlots=function(){return nM().slots},e.useTransitionState=rP,e.vModelCheckbox=lE,e.vModelDynamic={created(e,t,n){l$(e,t,n,null,"created")},mounted(e,t,n){l$(e,t,n,null,"mounted")},beforeUpdate(e,t,n,r){l$(e,t,n,r,"beforeUpdate")},updated(e,t,n,r){l$(e,t,n,r,"updated")}},e.vModelRadio=lN,e.vModelSelect=lI,e.vModelText=lw,e.vShow={beforeMount(e,{value:t},{transition:n}){e[i2]="none"===e.style.display?"":e.style.display,n&&t?n.beforeEnter(e):i6(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:r}){!t!=!n&&(r?t?(r.beforeEnter(e),i6(e,!0),r.enter(e)):r.leave(e,()=>{i6(e,!1)}):i6(e,t))},beforeUnmount(e,{value:t}){i6(e,t)}},e.version=iM,e.warn=h,e.watch=function(e,t,n){return rC(e,t,n)},e.watchEffect=function(e,t){return rC(e,null,t)},e.watchPostEffect=r_,e.watchSyncEffect=rS,e.withAsyncContext=function(e){let t=i_(),n=e();return ix(),R(n)&&(n=n.catch(e=>{throw iS(t),e})),[n,()=>iS(t)]},e.withCtx=t5,e.withDefaults=function(e,t){return null},e.withDirectives=function(e,t){if(null===t6)return e;let n=iI(t6),r=e.dirs||(e.dirs=[]);for(let e=0;e{let n=e._withKeys||(e._withKeys={}),r=t.join(".");return n[r]||(n[r]=n=>{if(!("key"in n))return;let r=H(n.key);if(t.some(e=>e===r||lF[e]===r))return e(n)})},e.withMemo=function(e,t,n,r){let i=n[r];if(i&&i$(i,e))return i;let l=t();return l.memo=e.slice(),l.memoIndex=r,n[r]=l},e.withModifiers=(e,t)=>{let n=e._withMods||(e._withMods={}),r=t.join(".");return n[r]||(n[r]=(n,...r)=>{for(let e=0;et5,e}({});
diff --git a/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/debug_session/debug_session_ext.ts b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/debug_session/debug_session_ext.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9934f0b7bc5bca2c96212afa60432bf765afe936
--- /dev/null
+++ b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/debug_session/debug_session_ext.ts
@@ -0,0 +1,858 @@
+/**
+ * Copyright (c) 2024 Huawei Technologies Co., Ltd.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import * as fs from "fs";
+import { DebugProtocol } from '@vscode/debugprotocol';
+import {
+ DebugSession, InitializedEvent, TerminatedEvent, StoppedEvent, ThreadEvent, OutputEvent, ContinuedEvent,
+ Thread, StackFrame, Scope, Source, Handles, Event, InvalidatedEvent
+} from '@vscode/debugadapter';
+import * as DebugAdapter from '@vscode/debugadapter';
+import { VariableScope, ExtendedVariable } from "./variable"
+import { InitialCommandStatus } from "./initial_command"
+import { StackVariable, VariableObjectChild } from '../machine_interface/backend';
+import { expandValue, expandValueStackListVariable } from '../utils/expansion';
+import { MIBase, execCmd } from '../machine_interface/mi_base';
+import backendGlobal, { globalKernelEvents, initBackendGlobal } from '../utils/backend_global';
+import { AsyncRecord } from "../utils/mi_parse_type/AsyncRecord";
+import { OutputRecord } from "../utils/mi_parse_type/OutputRecord";
+import { MemoryReference } from "./memory";
+
+let preRecord = null;
+
+export interface ReadMemoryInnerRequest {
+ variableName:string;
+ memoryReference:MemoryReference;
+ offset:number;
+ count:number;
+}
+
+export interface ReadMemoryInnerResponse extends ReadMemoryInnerRequest {
+ data:string[];
+}
+
+export class DebugSessionExt extends DebugSession {
+ protected miDebugger: MIBase;
+ protected variableHandles = new Handles();
+ protected variableHandlesReverse: { [id: string]: number } = {};
+ protected scopeHandlesReverse: { [key: string]: number } = {};
+ protected stackVariables: DebugProtocol.Variable[] = [];
+ protected initialRunCommand: InitialCommandStatus;
+ protected isInitialRunCommandFinished = false;
+
+ public constructor(debuggerLinesAndColumnsStartAt1: boolean, isServer: boolean = false) {
+ super(debuggerLinesAndColumnsStartAt1, isServer);
+ }
+
+ protected bindDebuggerEvents(): void {
+ this.miDebugger.on("error-fatal", (err: any) => {
+ this.sendEvent(new OutputEvent(`${err.toString()}\n`, "stderr"));
+ this.sendEvent(new TerminatedEvent());
+ });
+ this.miDebugger.on("quit", () => {
+ this.sendEvent(new TerminatedEvent());
+ });
+ this.miDebugger.on("exited-normally", () => {
+ this.sendEvent(new TerminatedEvent());
+ });
+ this.miDebugger.on("output", (type: string, msg: string) => {
+ // type: console(blue)/stdout(green)/stderr(red)
+ this.sendEvent(new OutputEvent(msg, type));
+ });
+ this.miDebugger.on("step", (info?: AsyncRecord) => {
+ const event: DebugProtocol.StoppedEvent = new StoppedEvent("step", info ? parseInt(info.getResult("thread-id")) : 1);
+ event.body.allThreadsStopped = info ? info.getResult("stopped-threads") == "all" : true;
+ this.sendEvent(event);
+ });
+ this.miDebugger.on("signal-received", (info: AsyncRecord) => {
+ const event: DebugProtocol.StoppedEvent = new StoppedEvent("exception", parseInt(info.getResult("thread-id")));
+ event.body.allThreadsStopped = info.getResult("stopped-threads") == "all";
+ this.sendEvent(event);
+ });
+ this.miDebugger.on("paused", (info: AsyncRecord) => {
+ const event: DebugProtocol.StoppedEvent = new StoppedEvent("pause", parseInt(info.getResult("thread-id")));
+ event.body.allThreadsStopped = info.getResult("stopped-threads") == "all";
+ this.sendEvent(event);
+ });
+ this.miDebugger.on("thread-created", (info: AsyncRecord) => {
+ this.sendEvent(new ThreadEvent("started", info.getResult("id")));
+ });
+ this.miDebugger.on("thread-exited", (info: AsyncRecord) => {
+ this.sendEvent(new ThreadEvent("exited", info.getResult("id")));
+ });
+ this.miDebugger.once("debug-ready", (() => {
+ this.sendEvent(new InitializedEvent());
+ this.sendEvent(new KernelFocus({ focus: false }));
+ initBackendGlobal();
+ }));
+
+ this.miDebugger.on("breakpoint-hit", this.handleBreakpointHit.bind(this));
+ globalKernelEvents.on('npuFocus', this.kernelFocus.bind(this));
+ }
+
+ kernelFocus() {
+ const focus = backendGlobal.kernel.isNpu;
+ this.sendEvent(new KernelFocus({ focus }));
+
+ if (focus) {
+ this.sendCurrentKernelInfo();
+ }
+ }
+
+ async sendCurrentKernelInfo() {
+ const allCores = await this.miDebugger.getKernelInfo();
+ const index = allCores.findIndex(i => i[7].includes('*')) + 1;
+
+ this.sendEvent(new ChangeKernelEvent({ type: allCores?.[index]?.[1], focusId: allCores?.[index]?.[0], allKernel: allCores }));
+ }
+
+ async sendMemoryInfo(args) {
+ const memory = await this.miDebugger.getMemory(args);
+
+ this.sendEvent(new Event('memoryResult', memory));
+ }
+
+ protected async customRequest(command: string, response: DebugProtocol.Response, args: any, request?: DebugProtocol.Request): Promise {
+ if (command === 'changeKernel') {
+ try {
+ await this.miDebugger.changeKernel(args);
+
+ this.handleBreakpointHit();
+ this.sendEvent(new InvalidatedEvent(['variables']));
+ } catch (e) {
+ this.sendEvent(new ChangeKernelError({ message: e }));
+ }
+ }
+
+ if (command === 'queryMemory') {
+ const innerResp = await this.readMemoryInnerRequest(args);
+
+ if (!innerResp || !innerResp?.memoryReference || innerResp?.memoryReference?.address === undefined) {
+ this.sendEvent(new Event('memoryResultError', innerResp));
+ } else {
+ this.sendEvent(new Event('memoryResult', innerResp));
+ }
+ }
+ }
+
+ protected async readMemoryInnerRequest(args:ReadMemoryInnerRequest):Promise {
+ const response:ReadMemoryInnerResponse = {...args, data:[]}
+ let memoryReference:MemoryReference;
+ if (args.variableName != undefined && args.variableName != "") {
+ memoryReference = await this.getMemoryReferenceByVariableName(args);
+ } else {
+ memoryReference = args.memoryReference;
+ }
+ if (memoryReference == undefined) {
+ response.memoryReference = undefined;
+
+ return response;
+ }
+ response.memoryReference = memoryReference;
+
+ let querySize = Math.min(args.count, parseInt(memoryReference.dataLength) - args.offset);
+ if (args.count <= 0 || querySize <= 0) {
+ response.data = [];
+ return response;
+ }
+ await this.miDebugger.readMemoryRequest(memoryReference, args.offset, args.count).then((res) => {
+ if (memoryReference.dataType == 'char[]') {
+ response.data = res;
+ } else {
+ let memoryVals = res.split(/\s/);
+ response.data = memoryVals;
+ }
+ }, err => {
+ throw new Error(err);
+ });
+ return response;
+ }
+
+ protected async getMemoryReferenceByVariableName(args:ReadMemoryInnerRequest):Promise {
+ // 0. 多行数据校验
+ if (args.variableName.split('\r\n').length > 1) {
+ return undefined;
+ }
+
+ // 1.evaluate 获取变量值,没有返回空
+ let variable = await this.miDebugger.evalExpression(args.variableName, 1, 1).then((res) => {
+ return res.getResult('value');
+ }, err => {
+ return undefined;
+ })
+ let memoryReference:MemoryReference = await this.getVariableMemoryReference(variable);
+ return memoryReference;
+ }
+
+ protected handleBreakpointHit(record?: AsyncRecord) {
+ if (!this.isInitialRunCommandFinished) {
+ this.isInitialRunCommandFinished = true;
+ }
+ const info = record || preRecord;
+ const event: DebugProtocol.StoppedEvent = new StoppedEvent("breakpoint", parseInt(info.getResult("thread-id")));
+ event.body.allThreadsStopped = info.getResult("stopped-threads") == "all";
+ this.sendEvent(event);
+
+ preRecord = info;
+ if (backendGlobal.kernel.isNpu) {
+ this.sendCurrentKernelInfo();
+ }
+ }
+
+ protected configurationDoneRequest(response: DebugProtocol.ConfigurationDoneResponse, args: DebugProtocol.ConfigurationDoneArguments): void {
+ this.miDebugger.execRun().then(() => {
+ this.sendResponse(response);
+ }).catch(err => {
+ this.sendErrorResponse(response, 1, `Exec-run error: ${err.toString()}`);
+ });
+ }
+
+ protected disconnectRequest(response: DebugProtocol.DisconnectResponse, args: DebugProtocol.DisconnectArguments): void {
+ this.miDebugger.exitDebugProcess();
+ this.sendResponse(response);
+ }
+
+ protected setBreakPointsRequest(response: DebugProtocol.SetBreakpointsResponse, args: DebugProtocol.SetBreakpointsArguments): void {
+ let path = args.source.path;
+ this.miDebugger.clearBreakPoints(path).then(() => {
+ const all = args.breakpoints.map(brk => {
+ return this.miDebugger.addBreakPoint({ sourceFileName: path, lineNumber: brk.line, breakCondition: brk.condition, breakCountCondition: brk.hitCondition });
+ });
+ Promise.all(all).then(brkpoints => {
+ const finalBrks = [];
+ brkpoints.forEach(brkp => {
+ if (brkp[0]) {
+ finalBrks.push(new DebugAdapter.Breakpoint(true, brkp[1].lineNumber));
+ }
+ });
+ response.body = {
+ breakpoints: finalBrks
+ };
+ this.sendResponse(response);
+ }, msg => {
+ this.sendErrorResponse(response, 1, `Set breakpiont error: ${msg.toString()}`);
+ });
+ }, msg => {
+ this.sendErrorResponse(response, 1, `Clear breakpoint error: ${msg.toString()}`);
+ });
+ }
+
+ protected setFunctionBreakPointsRequest(response: DebugProtocol.SetFunctionBreakpointsResponse, args: DebugProtocol.SetFunctionBreakpointsArguments): void {
+ const all = [];
+ args.breakpoints.forEach(brk => {
+ all.push(this.miDebugger.addBreakPoint({ raw: brk.name, breakCondition: brk.condition, breakCountCondition: brk.hitCondition }));
+ });
+ Promise.all(all).then(brkpoints => {
+ const finalBrks = [];
+ brkpoints.forEach(brkp => {
+ if (brkp[0]) {
+ finalBrks.push({ line: brkp[1].lineNumber });
+ }
+ });
+ response.body = {
+ breakpoints: finalBrks
+ };
+ this.sendResponse(response);
+ }, msg => {
+ this.sendErrorResponse(response, 1, `Set function breakpoint error: ${msg.toString()}`);
+ });
+ }
+
+ protected async setVariableRequest(response: DebugProtocol.SetVariableResponse, args: DebugProtocol.SetVariableArguments): Promise {
+ try {
+ await this.miDebugger.changeVariable(args.name, args.value);
+ response.body = {
+ value: args.value
+ };
+ this.sendResponse(response);
+ } catch (err) {
+ this.sendErrorResponse(response, 1, `Continue error: ${err}`);
+ }
+ }
+
+ protected stackTraceRequest(response: DebugProtocol.StackTraceResponse, args: DebugProtocol.StackTraceArguments): void {
+ this.miDebugger.getStackListFramesInfo(args.startFrame, args.levels, args.threadId).then(framesInfo => {
+ const ret: StackFrame[] = [];
+ framesInfo.forEach(frameInfo => {
+ let source = undefined;
+ let path = frameInfo.fullFileName;
+ if (path) {
+ source = new Source(frameInfo.fileName, path);
+ }
+
+ ret.push(new StackFrame(
+ this.threadAndLevelToFrameId(args.threadId, frameInfo.frameNumber),
+ frameInfo.functionName + "@" + frameInfo.pcAddr,
+ source,
+ frameInfo.pcLineNumber,
+ 0));
+ });
+ response.body = {
+ stackFrames: ret
+ };
+ this.sendResponse(response);
+ }, err => {
+ this.sendErrorResponse(response, 1, `Get Stack Trace: ${err.toString()}`);
+ });
+ }
+
+ protected threadsRequest(response: DebugProtocol.ThreadsResponse): void {
+ if (!this.miDebugger || !this.isInitialRunCommandFinished) {
+ this.sendResponse(response);
+ return;
+ }
+ this.miDebugger.getThreadsInfo().then(threadsInfo => {
+ response.body = {
+ threads: []
+ };
+ for (const threadInfo of threadsInfo) {
+ const threadName = threadInfo.targetId || "";
+ response.body.threads.push(new Thread(threadInfo.id, threadInfo.id + ":" + threadName));
+ }
+ this.sendResponse(response);
+ }).catch(error => {
+ this.sendErrorResponse(response, 1, `Get threads: ${error}`);
+ });
+ }
+
+ protected threadAndLevelToFrameId(threadId: number, level: number) {
+ return level << 16 | threadId;
+ }
+
+ protected frameIdToThreadAndLevel(frameId: number) {
+ return [frameId & 0xffff, frameId >> 16];
+ }
+
+ protected scopesRequest(response: DebugProtocol.ScopesResponse, args: DebugProtocol.ScopesArguments): void {
+ const scopes = new Array();
+ const [threadId, level] = this.frameIdToThreadAndLevel(args.frameId);
+
+ const createScope = (scopeName: string, expensive: boolean): Scope => {
+ const key: string = scopeName + ":" + threadId + ":" + level;
+ let handle: number;
+
+ if (Object.prototype.hasOwnProperty.call(this.scopeHandlesReverse, key)) {
+ handle = this.scopeHandlesReverse[key];
+ } else {
+ handle = this.variableHandles.create(new VariableScope(scopeName, threadId, level));
+ this.scopeHandlesReverse[key] = handle;
+ }
+
+ return new Scope(scopeName, handle, expensive);
+ };
+
+ scopes.push(createScope("Local", false));
+ scopes.push(createScope("Registers", false));
+
+ response.body = {
+ scopes: scopes
+ };
+ this.sendResponse(response);
+ }
+
+ protected async variablesRequest(response: DebugProtocol.VariablesResponse, args: DebugProtocol.VariablesArguments): Promise {
+ const variables: DebugProtocol.Variable[] = [];
+ const id: VariableScope | string | VariableObjectChild = this.variableHandles.get(args.variablesReference);
+
+ const createVariable = (arg) => {
+ return this.variableHandles.create(arg);
+ };
+
+ const findOrCreateVariable = (varObjChild: VariableObjectChild): number => {
+ let id: number;
+ if (Object.prototype.hasOwnProperty.call(this.variableHandlesReverse, varObjChild.name)) {
+ id = this.variableHandlesReverse[varObjChild.name];
+ } else {
+ id = createVariable(varObjChild);
+ this.variableHandlesReverse[varObjChild.name] = id;
+ }
+ return varObjChild.isCompound() ? id : 0;
+ };
+
+ if (id instanceof VariableScope) {
+ if (id.name === 'Registers') {
+ try {
+ response.body = {
+ variables: []
+ };
+ if (backendGlobal.kernel.isNpu) {
+ await this.miDebugger.getKernelRegisterInfo().then(data => {
+ const registerVariableArr = data;
+ response.body.variables = registerVariableArr;
+ }).catch(err => { });
+ } else {
+ const regNamesResp = await this.miDebugger.getRegistersNames();
+ const regNames: string[] = regNamesResp.getResult("register-names");
+
+ const regValuesResp = await this.miDebugger.getRegistersValues();
+ const regValues = regValuesResp.getResult("register-values");
+
+ regValues.forEach((pair) => {
+ const regNum = Number.parseInt(pair[0][1]);
+ const regName = regNames[regNum];
+ let registerVariable = {
+ name: regName,
+ type: '',
+ value: pair[1][1],
+ variablesReference: 0
+ }
+ response.body.variables.push(registerVariable);
+ })
+ }
+
+ this.sendResponse(response);
+ } catch (err) {
+ this.sendErrorResponse(response, 1, `Expand variable error: ${err}`);
+ }
+ } else {
+ let stackVariables: StackVariable[];
+ try {
+ let result = await this.miDebugger.getStackVariables(id.threadId, id.level);
+ stackVariables = result.getResult("variables");
+
+ for (const stackVariable of stackVariables) {
+ if (stackVariable.value !== undefined) {
+ let expanded = expandValueStackListVariable(createVariable, { [stackVariable["name"]]: stackVariable["value"] });
+ if (expanded) {
+ variables.push(expanded[0]);
+ }
+ } else {
+ let newVariable = {
+ name: stackVariable.name,
+ type: stackVariable.type,
+ value: stackVariable.type,
+ memoryReference: undefined,
+ variablesReference: createVariable(stackVariable.name)
+ }
+ variables.push(newVariable);
+ }
+ }
+ response.body = {
+ variables: variables
+ };
+ /* 保存stack变量信息 */
+ this.stackVariables = variables;
+ this.sendResponse(response);
+ } catch (err) {
+ this.sendErrorResponse(response, 1, `Expand variable error: ${err}`);
+ }
+ }
+ } else if (typeof id == "string") {
+ let variable;
+ try {
+ variable = await this.miDebugger.evalExpression(JSON.stringify(id), 0, 0);
+ let needExpand = true;
+
+ if (id == "this") {
+ needExpand = false;
+ }
+
+ let expandInput = variable.getResult("value");
+ if (typeof expandInput == "string") {
+ // VARIABLE显示this,x等, value是字符串
+ expandInput = { "value": expandInput };
+ }
+
+ try {
+ let expanded = expandValue(createVariable, expandInput, needExpand);
+ if (!expanded) {
+ this.sendErrorResponse(response, 1, `Expand variable error`);
+ } else {
+ response.body = {
+ variables: expanded
+ };
+ this.sendResponse(response);
+ }
+ } catch (e) {
+ this.sendErrorResponse(response, 1, `Expand variable error: ${e}`);
+ }
+ } catch (err) {
+ this.sendErrorResponse(response, 1, `Expand variable error: ${err}`);
+ }
+ } else if (typeof id == "object") {
+ if (id instanceof VariableObjectChild) {
+ let children: VariableObjectChild[];
+ try {
+ children = await this.miDebugger.varListChildren(id.name);
+ const vars = children.map(child => {
+ const varId = findOrCreateVariable(child);
+ child.id = varId;
+ return child.toDebugProtocolVariable();
+ });
+
+ response.body = {
+ variables: vars
+ };
+ this.sendResponse(response);
+ } catch (err) {
+ this.sendErrorResponse(response, 1, `Expand variable error: ${err}`);
+ }
+ } else {
+ response.body = {
+ variables: id
+ };
+ this.sendResponse(response);
+ }
+ } else {
+ response.body = {
+ variables: variables
+ };
+ this.sendResponse(response);
+ }
+ }
+
+ protected pauseRequest(response: DebugProtocol.ContinueResponse, args: DebugProtocol.ContinueArguments): void {
+ this.miDebugger.interrupt().then(done => {
+ this.sendResponse(response);
+ }, msg => {
+ this.sendErrorResponse(response, 1, `Pause error: ${msg}`);
+ });
+ }
+
+ protected reverseContinueRequest(response: DebugProtocol.ReverseContinueResponse, args: DebugProtocol.ReverseContinueArguments): void {
+ this.miDebugger.continue(true).then(done => {
+ this.sendResponse(response);
+ }, msg => {
+ this.sendErrorResponse(response, 1, `Continue error: ${msg}`);
+ });
+ }
+
+ protected continueRequest(response: DebugProtocol.ContinueResponse, args: DebugProtocol.ContinueArguments): void {
+ this.miDebugger.continue().then(done => {
+ this.sendResponse(response);
+ }, msg => {
+ this.sendErrorResponse(response, 1, `Continue error: ${msg}`);
+ });
+ }
+
+ protected stepInRequest(response: DebugProtocol.NextResponse, args: DebugProtocol.NextArguments): void {
+ this.miDebugger.step().then(done => {
+ this.sendResponse(response);
+ }, msg => {
+ this.sendErrorResponse(response, 1, `Step in error: ${msg}`);
+ });
+ }
+
+ protected stepOutRequest(response: DebugProtocol.NextResponse, args: DebugProtocol.NextArguments): void {
+ this.miDebugger.stepOut().then(done => {
+ this.sendResponse(response);
+ }, msg => {
+ this.sendErrorResponse(response, 1, `Step out error: ${msg}`);
+ });
+ }
+
+ protected stepBackRequest(response: DebugProtocol.StepBackResponse, args: DebugProtocol.StepBackArguments): void {
+ this.miDebugger.step(true).then(done => {
+ this.sendResponse(response);
+ }, msg => {
+ this.sendErrorResponse(response, 1, `Step back error: ${msg}`);
+ });
+ }
+
+ protected nextRequest(response: DebugProtocol.NextResponse, args: DebugProtocol.NextArguments): void {
+ this.miDebugger.next().then(done => {
+ this.sendResponse(response);
+ }, msg => {
+ this.sendErrorResponse(response, 1, `Step over error: ${msg}`);
+ });
+ }
+
+ protected gotoTargetsRequest(response: DebugProtocol.GotoTargetsResponse, args: DebugProtocol.GotoTargetsArguments): void {
+ const path: string = args.source.path;
+ this.miDebugger.goto(path, args.line).then(done => {
+ response.body = {
+ targets: [{
+ id: 1,
+ label: args.source.name,
+ column: args.column,
+ line: args.line
+ }]
+ };
+ this.sendResponse(response);
+ }, msg => {
+ this.sendErrorResponse(response, 1, `Jump error: ${msg}`);
+ });
+ }
+
+ protected gotoRequest(response: DebugProtocol.GotoResponse, args: DebugProtocol.GotoArguments): void {
+ this.sendResponse(response);
+ }
+
+ protected evaluateRequest(response: DebugProtocol.EvaluateResponse, args: DebugProtocol.EvaluateArguments): void {
+ if(args.context == "hover" && args.expression.trim() == ""){
+ return;
+ }
+
+ const [threadId, level] = this.frameIdToThreadAndLevel(args.frameId);
+ if (args.context == "watch" || args.context == "hover") {
+ const createVariable = (arg) => {
+ return this.variableHandles.create(arg);
+ };
+
+ this.miDebugger.evalExpression(args.expression, threadId, level).then((res) => {
+ /* 获取变量variablesReference便于variable request查询 */
+ let varReference: number;
+ let variables: DebugProtocol.Variable[] = this.stackVariables;
+ for (let i = 0; i < variables.length; i++) {
+ if (args.expression == variables[i]['name']) {
+ varReference = variables[i]['variablesReference'];
+ }
+ }
+ if (!varReference) {
+ varReference = createVariable(args.expression);
+ }
+
+ response.body = {
+ variablesReference: varReference,
+ result: JSON.stringify(res.getResult("value")),
+ };
+ this.sendResponse(response);
+ }, msg => {
+ if (args.context != "hover") {
+ // hover到某个字符会触发错误
+ this.sendErrorResponse(response, 1, msg.toString());
+ }
+ });
+ } else {
+ this.miDebugger.sendUserInput(args.expression, threadId, level).then(output => {
+ if (typeof output == "undefined") {
+ response.body = {
+ result: "",
+ variablesReference: 0
+ };
+ }
+ else {
+ response.body = {
+ result: JSON.stringify(output),
+ variablesReference: 0
+ };
+ }
+ this.sendResponse(response);
+ }, msg => {
+ this.sendErrorResponse(response, 1, msg.toString());
+ });
+ }
+ }
+
+ protected async getVariableMemoryReference(variableVal): Promise {
+ let address: string;
+ let memoryLocation: string;
+ let datalength:string;
+ let dataType:string;
+
+ let tensorKey = findTensorKey(variableVal);
+ if (tensorKey != undefined && tensorKey.includes('BaseGlobalTensor')) {
+ address = getGlobalTensorAddress(variableVal, tensorKey);
+ memoryLocation = 'GM';
+ datalength = getGlobalTensorDataLen(variableVal);
+ dataType = getDataTypeByTensorKey(tensorKey);
+ } else if (variableVal.address_ != undefined && variableVal.address_.datalen == undefined) {
+ address = variableVal.address_;
+ memoryLocation = 'GM';
+ datalength = getGlobalTensorDataLen(variableVal);
+ dataType = getDataTypeByTensorKey(tensorKey);
+ } else if (tensorKey != undefined && tensorKey.includes('BaseLocalTensor')) {
+ address = getLocalTensorAddress(variableVal, tensorKey);
+ let logicPos = getLocalTensorLogicPos(variableVal, tensorKey);
+ // logicPos打印值转成ascII码的值,仅适配UB
+ logicPos = logicPos.replace('\\\\\\\\t', '\t').replace('\\\\\\\\0', '\t').replace('\\\\\\\\v', '\v').replace('\\\\\\\\n', '\n');
+ const tPosition = getTPositionByLogicPos(logicPos.charCodeAt(0));
+ memoryLocation = await getMemoryLocationByTPosition(tPosition);
+ datalength = getLocalTensorDataLen(variableVal, tensorKey);
+ dataType = getDataTypeByTensorKey(tensorKey);
+ } else if (variableVal.address_ != undefined && variableVal.address_.datalen != undefined) {
+ address = variableVal.address_.bufferAddr;
+ memoryLocation = 'UB';
+ datalength = variableVal.address_.datalen;
+ dataType = getDataTypeByTensorKey(tensorKey);
+ } else if (typeof variableVal === 'string' && !/^\d+$/.test(variableVal)) {
+ address = variableVal.substring(0, 18);
+ memoryLocation = 'COMMON';
+ } else {
+ address = undefined;
+ }
+ return {
+ memoryLocation:memoryLocation,
+ address:address,
+ dataLength:datalength,
+ dataType:dataType
+ };
+ }
+}
+
+class ChangeKernelEvent extends Event {
+ body: {
+ type: '',
+ focusId: '',
+ allKernel: []
+ }
+
+ public constructor(body) {
+ super('changeKernel');
+
+ this.body = {
+ ...this.body,
+ ...body
+ };
+ }
+}
+
+class KernelFocus extends Event {
+ body: {
+ focus: false
+ }
+
+ public constructor(body) {
+ super('kernelFocus');
+
+ this.body = {
+ ...this.body,
+ ...body
+ };
+ }
+}
+
+class ChangeKernelError extends Event {
+ body: {
+ message: ''
+ }
+
+ public constructor(body) {
+ super('changeKernelError');
+
+ this.body = {
+ ...this.body,
+ ...body
+ };
+ }
+}
+
+function getLocalTensorLogicPos(localTensorVal, tensorKey): string {
+ tensorKey = (tensorKey.length != 0) ? tensorKey : findTensorKey(localTensorVal);
+ return localTensorVal[tensorKey].address_.logicPos;
+}
+
+function getLocalTensorAddress(localTensorVal, tensorKey): string {
+ tensorKey = (tensorKey.length != 0) ? tensorKey : findTensorKey(localTensorVal);
+ return localTensorVal[tensorKey].address_.bufferAddr;
+}
+
+function getLocalTensorDataLen(localTensorVal, tensorKey): string {
+ tensorKey = (tensorKey.length != 0) ? tensorKey : findTensorKey(localTensorVal);
+ return localTensorVal[tensorKey].address_.dataLen;
+}
+
+function getGlobalTensorAddress(globalTensorVal, tensorKey): string {
+ tensorKey = (tensorKey.length != 0) ? tensorKey : findTensorKey(globalTensorVal);
+ return globalTensorVal[tensorKey].address_;
+}
+
+function getGlobalTensorDataLen(globalTensorVal): string {
+ return globalTensorVal.bufferSize_;
+}
+
+function findTensorKey(tensorVal): string {
+ let firstKey: string | undefined;
+ for (let key in tensorVal) {
+ if (key.startsWith('AscendC::')) {
+ firstKey = key;
+ break;
+ }
+ }
+ return firstKey;
+}
+
+function getDataTypeByTensorKey(tensorKey): string {
+ const keywordToDatatypeMap:{[key:string]:string} = {
+ 'bool':'bool',
+ 'char':'char[]',
+ 'int8_t':'int8_t[]',
+ 'signed char':'int8_t[]',
+ 'uint8_t':'uint8_t[]',
+ 'unsigned char':'uint8_t[]',
+ 'int16_t':'int16_t[]',
+ 'uint16_t':'uint16_t[]',
+ 'int32_t':'int32_t[]',
+ 'int':'int32_t[]',
+ 'signed int':'int32_t[]',
+ 'uint':'uint32_t[]',
+ 'uint32_t':'uint32_t[]',
+ 'unsigned int':'uint32_t[]',
+ 'int64_t':'int64_t[]',
+ 'uint64_t':'uint64_t[]',
+ '__bf16':'bfloat16[]',
+ '__fp16':'float16[]',
+ 'half':'float16[]',
+ 'float':'float32[]',
+ 'double':'float64[]',
+ 'uint128_t':'uint128_t[]'
+ }
+ for (const [keyword, datatype] of Object.entries(keywordToDatatypeMap)) {
+ if (tensorKey.includes(`<${keyword}>`)) {
+ return datatype;
+ }
+ }
+}
+
+function getTPositionByLogicPos(index): string {
+ const tPositions = ['GM', 'A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'C01', 'C02', 'VECIN', 'VECOUT', 'VECCALC', 'LCM', 'SPM', 'SHM', 'TSCM', 'MAX'];
+ return tPositions[index];
+}
+
+
+async function getMemoryLocationByTPosition(tPosition): Promise {
+ let SocVersion = await execCmd("npu-smi info|awk 'NR==7 {print $3}'").catch(err => {throw err});
+
+ // 当前仅适配220芯片,对应910B
+ const tPositionToMemoryLocationMapFor220:{[key:string]:string} = {
+ 'GM':'GM',
+ 'A1':'L1',
+ 'B1':'L1',
+ 'TSCM':'L1',
+ 'VECIN':'UB',
+ 'VECOUT':'UB',
+ 'VECCALC':'UB',
+ 'A2':'L0A',
+ 'B2':'L0B',
+ 'C1':'L1',
+ 'C2':'BIAS',
+ 'C01':'L0C',
+ 'C02':'GM',
+ 'C2PIPE2GM':'FIXBUF'
+ }
+ // 当前仅适配200芯片,对应310P
+ const tPositionToMemoryLocationMapFor200:{[key:string]:string} = {
+ 'GM':'GM',
+ 'A1':'L1',
+ 'B1':'L1',
+ 'TSCM':'L1',
+ 'VECIN':'UB',
+ 'VECOUT':'UB',
+ 'VECCALC':'UB',
+ 'A2':'L0A',
+ 'B2':'L0B',
+ 'C1':'L1',
+ 'C2':'BIAS',
+ 'C01':'L0C',
+ 'C02':'UB'
+ }
+
+ let tPositionToMemoryLocationMap = {};
+ if (SocVersion.includes('910')) {
+ tPositionToMemoryLocationMap = tPositionToMemoryLocationMapFor220;
+ } else if (SocVersion.includes('310')) {
+ tPositionToMemoryLocationMap = tPositionToMemoryLocationMapFor200;
+ } else {
+ throw new Error(`Unsupported npu SocVersion: ${SocVersion}`);
+ }
+
+ for (const [keyword, memoryLocation] of Object.entries(tPositionToMemoryLocationMap)) {
+ if (tPosition == keyword) {
+ return String(memoryLocation);
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/debug_session/initial_command.ts b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/debug_session/initial_command.ts
new file mode 100644
index 0000000000000000000000000000000000000000..827604bfd464587de4d763873f89c2fd83cff2e1
--- /dev/null
+++ b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/debug_session/initial_command.ts
@@ -0,0 +1,12 @@
+/**
+ * Copyright (c) 2024 Huawei Technologies Co., Ltd.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+export enum InitialCommandStatus {
+ CONTINUE,
+ RUN,
+ NONE
+}
\ No newline at end of file
diff --git a/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/debug_session/memory.ts b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/debug_session/memory.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2ac44a2244dcc0e7331569c0b5e957590d71bac7
--- /dev/null
+++ b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/debug_session/memory.ts
@@ -0,0 +1,17 @@
+/**
+ * Copyright (c) 2024 Huawei Technologies Co., Ltd.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+export interface MemoryReference {
+ // GM/UB/L0A/L0B/L0C/COMMON
+ memoryLocation:string;
+ // number or 0x123
+ address:string;
+ // >= 0
+ dataLength:string;
+ // int64/int32/int16/int8/uint8/fp64/fp32/fp16/bf16
+ dataType?:string;
+}
diff --git a/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/debug_session/msdebug_session.ts b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/debug_session/msdebug_session.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7232816d0bcc6dba5b7c2ff140b15331ff0f6852
--- /dev/null
+++ b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/debug_session/msdebug_session.ts
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2024 Huawei Technologies Co., Ltd.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import { InitialCommandStatus } from "./initial_command";
+import { DebugSessionExt } from './debug_session_ext';
+import { DebugSession, OutputEvent } from '@vscode/debugadapter';
+import { DebugProtocol } from '@vscode/debugprotocol'
+import { MsdebugMI } from "../machine_interface/msdebug_mi";
+import { processEnv, checkAndPrintPostLoadMessage} from "../machine_interface/process_env"
+import {getMsdebugMiPath} from "../machine_interface/mi_base"
+
+export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArguments {
+ cwd: string;
+ target: string;
+ targetArgs: string[];
+ msdebugMiPath: string;
+ environment: any;
+ args: string;
+ printMiInput: boolean;
+ printMiOutput: boolean;
+ skipEnvCheck: boolean;
+ environmentScripts: string[];
+}
+
+class MsDebugDebugSession extends DebugSessionExt {
+ protected initializeRequest(response: DebugProtocol.InitializeResponse, args: DebugProtocol.InitializeRequestArguments): void {
+ response.body.supportsGotoTargetsRequest = true;
+ response.body.supportsHitConditionalBreakpoints = true;
+ response.body.supportsConfigurationDoneRequest = true;
+ response.body.supportsConditionalBreakpoints = true;
+ response.body.supportsFunctionBreakpoints = true;
+ response.body.supportsEvaluateForHovers = true;
+ response.body.supportsReadMemoryRequest = true;
+ this.sendResponse(response);
+ }
+
+ protected async launchRequest(response: DebugProtocol.LaunchResponse, args: LaunchRequestArguments): Promise {
+ try {
+ let envs = processEnv(args.environment, args.environmentScripts);
+ let msdebugMiPath:string = await getMsdebugMiPath(args.msdebugMiPath, envs);
+ this.miDebugger = new MsdebugMI(msdebugMiPath, envs);
+ this.bindDebuggerEvents();
+ this.miDebugger.printMiInput = !!args.printMiInput;
+ this.miDebugger.printMiOutput = !!args.printMiOutput;
+ this.miDebugger.targetArgs = args.targetArgs;
+
+ if (!args.skipEnvCheck){
+ checkAndPrintPostLoadMessage(this.miDebugger.envs, (msg)=>this.miDebugger.log("console", msg));
+ }
+
+ } catch (err) {
+ this.sendEvent(new OutputEvent(`Failed to launch: ${String(err.message)}`, "stderr"));
+ this.sendErrorResponse(response, 1, `Failed to launch: ${String(err.message)}`);
+ return;
+ }
+ this.miDebugger.load(args.cwd, args.target).then(() => {
+ this.sendResponse(response);
+ }, err => {
+ this.sendErrorResponse(response, 1, `Failed to load MI Debugger: ${err.toString()}`);
+ });
+
+ }
+}
+
+DebugSession.run(MsDebugDebugSession);
\ No newline at end of file
diff --git a/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/debug_session/variable.ts b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/debug_session/variable.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7c0422fa215bf30a7026474ef04128f45471ee44
--- /dev/null
+++ b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/debug_session/variable.ts
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2024 Huawei Technologies Co., Ltd.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+export class ExtendedVariable {
+ constructor(public readonly name, public readonly options) {
+ }
+}
+
+export class VariableScope {
+ constructor(public readonly name: string, public readonly threadId: number, public readonly level: number) {
+ }
+
+ public static getVariableName(handle: number, name: string): string {
+ return `var_${handle}_${name}`;
+ }
+}
\ No newline at end of file
diff --git a/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/extension.ts b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/extension.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d1d2e9a7bbdf736bb56eb60404f5d2f93c585fa1
--- /dev/null
+++ b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/extension.ts
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2024 Huawei Technologies Co., Ltd.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import * as vscode from "vscode";
+import kernelSwitchView from "./views/switch_kernel";
+import memoryView from "./views/memory_view";
+import kernelView from './views/kernel_view';
+
+export function activate(context: vscode.ExtensionContext) {
+ console.log('Congratulations, your extension "MindStudio Debug VSCode Plugin" is now active!');
+
+ memoryView.init(context);
+
+ kernelView.init(context);
+}
diff --git a/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/machine_interface/backend.ts b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/machine_interface/backend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0f878957e85465e6503bcc6523b6ba7fc3f0b176
--- /dev/null
+++ b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/machine_interface/backend.ts
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2024 Huawei Technologies Co., Ltd.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import { Variable } from "@vscode/debugadapter";
+import { DebugProtocol } from "@vscode/debugprotocol/lib/debugProtocol";
+
+export interface Breakpoint {
+ sourceFileName?: string;
+ lineNumber?: number;
+ raw?: string;
+ breakCondition: string;
+ breakCountCondition?: string;
+}
+
+export interface ThreadInfo {
+ id: number;
+ targetId: string;
+}
+
+export interface StackFrameInfo {
+ frameNumber: number;
+ pcAddr: string;
+ functionName: string;
+ fileName: string;
+ fullFileName: string;
+ pcLineNumber: number;
+}
+
+export interface StackVariable {
+ name: string;
+ value: string;
+ type: string;
+ raw?: any;
+}
+
+
+export class VariableObjectChild {
+ name: string;
+ expressionShown: string;
+ childrenNum: number;
+ type: string;
+ value: string;
+ globalThreadId: string;
+ isFrozen: boolean;
+ isDynamic: boolean;
+ displayhint: string;
+ selectedRangehasMore: boolean;
+ id: number;
+ constructor(node: any) {
+ this.name = node["name"];
+ this.expressionShown = node["exp"];
+ this.childrenNum = parseInt(node["numchild"]);
+ this.type = node["type"];
+ this.value = node["value"];
+ this.globalThreadId = node["thread-id"];
+ this.isFrozen = !!node["frozen"];
+ this.isDynamic = !!node["dynamic"];
+ this.displayhint = node["displayhint"];
+ this.selectedRangehasMore = !!node["has_more"];
+ }
+
+ public isCompound(): boolean {
+ return this.childrenNum > 0 ||
+ this.value === "{...}" ||
+ (this.isDynamic && (this.displayhint === "array" || this.displayhint === "map"));
+ }
+
+ public toDebugProtocolVariable(): DebugProtocol.Variable {
+ let protocoName = this.expressionShown;
+ let protocoEvaluateName = this.name;
+ let protocoVal = (this.value === void 0) ? "" : this.value;
+ let protocoType = this.type;
+ let protocoVariablesReference = this.id;
+ const res: DebugProtocol.Variable = {
+ name: protocoName,
+ evaluateName: protocoEvaluateName,
+ value: protocoVal,
+ type: protocoType,
+ variablesReference: protocoVariablesReference
+ };
+ return res;
+ }
+}
\ No newline at end of file
diff --git a/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/machine_interface/mi_base.ts b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/machine_interface/mi_base.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2aa05ef7a486dc315816f42022927b6d6a16eaaf
--- /dev/null
+++ b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/machine_interface/mi_base.ts
@@ -0,0 +1,743 @@
+/**
+ * Copyright (c) 2024 Huawei Technologies Co., Ltd.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import { Breakpoint, ThreadInfo, StackFrameInfo, StackVariable, VariableObjectChild } from "./backend";
+import * as ChildProcess from "child_process";
+import { EventEmitter } from "events";
+import * as path from "path";
+import { kernelChangeFocus } from "../utils/backend_global";
+import { escape } from "../utils/str_util";
+import { MIParser } from "../utils/mi_parse_type/MIParser";
+import { OutputRecord } from "../utils/mi_parse_type/OutputRecord";
+import { ResultRecord, ResultRecordType } from "../utils/mi_parse_type/ResultRecord";
+import { StreamRecord } from "../utils/mi_parse_type/StreamRecord";
+import { AsyncRecord, AsyncRecordType } from "../utils/mi_parse_type/AsyncRecord";
+import { MemoryReference } from "../debug_session/memory"
+import {isFileExist} from "../utils/file_util"
+import {validatePath} from "../utils/file_util"
+import {exec} from "child_process"
+import {ErrorStreamRecordHandler} from "../utils/mi_parse_type/ErrorStreamRecordHandler"
+
+export class MIBase extends EventEmitter {
+ constructor(public application: string, envs: any) {
+ super();
+
+ this.envs = envs;
+ this.miParser = new MIParser();
+ this.application = application;
+ }
+
+ async getMemory(args): Promise {
+ return { cc: 'cc' };
+ }
+
+ async getKernelInfo(): Promise {
+ const res = await this.sendCliCommand('ascend info cores');
+
+ const infoStr = res.getResult('result').replace(/\\{1,3}[trn]/g, '');
+ const content = infoStr.trim() || '';
+ const contentSplit = content.split(/\s{2,}/);
+ const results = contentSplit.slice(5);
+ const allLine = results.length / 8;
+ const allCores = [];
+
+ for (let i = 0; i < allLine; i++) {
+ const coreInfo = [];
+
+ for (let j = 0; j < 8; j++) {
+ coreInfo.push(results[i * 8 + j]);
+ }
+
+ allCores.push(coreInfo);
+ }
+
+ return allCores;
+ }
+
+ async changeKernel(kernelInfo): Promise {
+ const type = kernelInfo.split(' ')[0];
+ const id = kernelInfo.split(' ')[1];
+
+ const res = await this.sendCliCommand(`ascend ${type} ${id}`);
+ const infoStr = res.getResult('result');
+
+ if (!infoStr) {
+ return Promise.reject(`error: Invalid ${type === 'aic' ? 'aicore' : 'vectorcore'} index '${id}'`);
+ }
+ }
+
+ async getKernelRegisterInfo(): Promise {
+ return new Promise((resolve, reject) => {
+ this.sendCliCommand('register read -a').then(result => {
+ let infoStr = result.getResult("result");
+ const content = infoStr.trim() || '';
+ const contentSplit = content.split(/\s{2,}/);
+ let registerVariableArr = [];
+ for (const element of contentSplit) {
+ const match = element.match(/^([a-zA-Z_\-][a-zA-Z0-9_\-]*|\[\d+\]|\s*)\s*=\s*([a-zA-Z0-9_\-]*)n?/);
+ if (match) {
+ let regName = match[1];
+ let regValue = match[2];
+ let registerVariable = {
+ name: regName,
+ type: '',
+ value: regValue,
+ variablesReference: 0
+ }
+ registerVariableArr.push(registerVariable)
+ }
+ }
+ resolve(registerVariableArr);
+ })
+ });
+ }
+
+ async load(cwd: string, target: string, targetArgs: string[] = []): Promise {
+ let userHome = await getUserHomePath();
+ if (!validatePath(cwd, userHome)) {
+ throw new Error(`Invalid path for cwd param.cwd=${cwd}`);
+ }
+
+ if (!path.isAbsolute(target) && isFileExist(cwd, target)) {
+ target = path.join(cwd, target);
+ }
+
+ if (!validatePath(target, userHome)) {
+ throw new Error(`Invalid path for target with cwd.cwd=${cwd}, new target=${target}`);
+ }
+
+ return new Promise((resolve, reject) => {
+ this.process = ChildProcess.spawn(this.application, [], { cwd: cwd, env: this.envs });
+ this.process.stdin.on('error', (e: any) => {
+ this.log('stderr', e?.stack || e);
+ });
+ this.process.stdout.on("data", (data: any) => {
+ this.processStdout(data);
+ });
+ this.process.stderr.on("data", (data: any) => {
+ this.processStderr(data);
+ });
+ this.process.on("exit", () => {
+ this.emit("quit");
+ });
+ this.process.on("error", (err) => {
+ this.emit("error-fatal", err);
+ });
+ const promises = this.initCommands(target);
+
+ Promise.all(promises).then(() => {
+ this.emit("debug-ready");
+ resolve(undefined);
+ }, reject);
+ });
+ }
+
+ protected initCommands(target: string, targetArgs: string[] = []) {
+ const cmds = [
+ this.sendCommand("gdb-set target-async on"),
+ new Promise(resolve => {
+ this.sendCommand("list-features").then(done => {
+ this.features = done.getResult("features");
+ resolve(undefined);
+ }, err => {
+ this.features = [];
+ resolve(undefined);
+ });
+ }),
+ this.sendCommand("file-exec-and-symbols \"" + escape(target) + "\"")
+ ];
+ if (targetArgs != undefined && targetArgs.length != 0) {
+ cmds.push(this.sendCliCommand(`settings set target.run-args ${escape(targetArgs.join(' '))}`));
+ }
+
+ return cmds;
+ }
+
+ private processStdout(data: any) {
+ this.outBuffer += data.toString("utf8");
+ const nPos = this.outBuffer.lastIndexOf('\n');
+ if (nPos != -1) {
+ this.onOutput(this.outBuffer.substring(0, nPos));
+ this.outBuffer = this.outBuffer.substring(nPos + 1);
+ }
+ }
+
+ private processStderr(data) {
+ this.errbuf += data.toString("utf8");
+ const nPos = this.errbuf.lastIndexOf('\n');
+ if (nPos != -1) {
+ const lines = this.errbuf.substring(0, nPos).split("\n");
+ this.errbuf = this.errbuf.substring(nPos + 1);
+ lines.forEach(line => {
+ this.log("stderr", line);
+ });
+ }
+ }
+
+ private handleResultRecord(record: ResultRecord) {
+ if (record.getToken() !== undefined && this.handlers[record.getToken()]) {
+ this.handlers[record.getToken()](record);
+ delete this.handlers[record.getToken()];
+ if (this.userInputCmdTokens.has(record.getToken())) {
+ this.userInputCmdTokens.delete(record.getToken());
+ }
+ }
+ }
+
+ private handleAsyncExecRecord(record: AsyncRecord) {
+ // 返回*开头的信息
+ let execClass = record.getClass();
+ switch (execClass) {
+ case "stopped":
+ const stopReason = record.getResult("reason");
+ if (stopReason == undefined) {
+ this.emit("step", record);
+ }
+ else {
+ switch (stopReason) {
+ case "breakpoint-hit":
+ kernelChangeFocus(record.getResult("is-device") === 'true');
+ this.emit("breakpoint-hit", record);
+ break;
+ case "watchpoint-trigger":
+ case "read-watchpoint-trigger":
+ case "access-watchpoint-trigger":
+ case "function-finished":
+ case "location-reached":
+ case "end-stepping-range":
+ case "watchpoint-scope":
+ case "solib-event":
+ case "syscall-entry":
+ case "syscall-return":
+ case "fork":
+ case "vfork":
+ case "exec":
+ this.emit("step", record);
+ break;
+ case "signal-received":
+ if (record.getResult("signal-meaning") == "Interrupt") {
+ this.emit("paused", record);
+ }
+ else {
+ this.emit("signal-received", record);
+ }
+ break;
+ case "exited-normally":
+ this.emit("exited-normally", record);
+ break;
+ case "exited":
+ this.log("stderr", `Program exited ${record.getResult("exit-code")}`);
+ this.emit("exited-normally", record);
+ break;
+ default:
+ this.log("stderr", "Unkown stop reason: " + stopReason);
+ break;
+ }
+ }
+ break;
+ case "running":
+ this.emit("running", record);
+ break;
+ default:
+ this.log("stderr", JSON.stringify(record));
+ break;
+ }
+ }
+
+ private handleAsyncNotifyRecord(record: AsyncRecord) {
+ // 返回=开头的信息
+ switch (record.getClass()) {
+ case "thread-created":
+ this.emit("thread-created", record);
+ break;
+ case "thread-exited":
+ this.emit("thread-exited", record);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private handleAsyncStatusRecord(record: AsyncRecord) {
+ // 返回+开头的信息,预留
+ }
+
+ private handleAsyncRecord(record: AsyncRecord) {
+ let recordType = record.getType();
+ switch (recordType) {
+ case AsyncRecordType.EXEC:
+ this.handleAsyncExecRecord(record);
+ break;
+ case AsyncRecordType.NOTIFY:
+ this.handleAsyncNotifyRecord(record);
+ break;
+ case AsyncRecordType.STATUS:
+ this.handleAsyncStatusRecord(record);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private handleStreamRecord(record: StreamRecord) {
+ if (record.getCString().includes('[ERROR]')) {
+ let handler = new ErrorStreamRecordHandler(record.getCString());
+ const errorLog = handler.handle();
+ if (errorLog != '') {
+ this.log("stderr", `${String(errorLog)}`);
+ }
+ }
+ }
+
+ onOutput(line: string) {
+ const lines = line.split('\n');
+ lines.forEach(line => {
+ try {
+ let unknown = {"text": ""};
+ const miOutput: OutputRecord = this.miParser.parse(line, unknown);
+ if(unknown["text"] != "") {
+ // 未知格式输出
+ this.log("stdout", unknown["text"]);
+ return;
+ }
+
+ if (miOutput == null) {
+ // GDB Prompt
+ return;
+ }
+
+ if (this.userInputCmdTokens.has(miOutput.getToken())) {
+ let logContent:string;
+ if (miOutput.getResult('result') != undefined) {
+ let outputJson = JSON.stringify(miOutput.getResult('result'));
+ logContent = outputJson.replace(/\\\\n/g, '\r\n').replace(/\"$/, '').replace(/^\"/, '');
+ } else {
+ // e.g. log enable lldb commands
+ logContent = miOutput.response;
+ }
+ this.log("console", logContent);
+ }
+ if (!this.userInputCmdTokens.has(miOutput.getToken()) && this.printMiOutput) {
+ this.log("console", `MI Output: ${JSON.stringify(miOutput)}`);
+ }
+
+ if (miOutput) {
+ switch (miOutput.constructor) {
+ case AsyncRecord:
+ this.handleAsyncRecord(miOutput as AsyncRecord);
+ break;
+ case ResultRecord:
+ this.handleResultRecord(miOutput as ResultRecord);
+ break;
+ case StreamRecord:
+ this.handleStreamRecord(miOutput as StreamRecord);
+ break;
+ }
+ }
+ }
+ catch (error) {
+ this.log("stderr", `Encounter error: ${String(error)}`);
+ this.emit("quit");
+ }
+ });
+ }
+
+ execRun(): Promise {
+ var cmd:string = 'run';
+ if (this.targetArgs != undefined && this.targetArgs.length != 0) {
+ cmd = `run ${escape(this.targetArgs.join(' '))}`;
+ }
+ return new Promise((resolve, reject) => {
+ this.sendCliCommand(cmd).then((info) => {
+ if (info.getType() == "done")
+ resolve(undefined);
+ else
+ reject();
+ }, reject);
+ });
+ }
+
+ exitDebugProcess() {
+ const debugProc = this.process;
+ const toKillDebugProc = setTimeout(() => {
+ process.kill(-debugProc.pid);
+ }, 1000);
+ this.process.on("exit", function (code) {
+ clearTimeout(toKillDebugProc);
+ });
+ this.sendRaw("-gdb-exit");
+ }
+
+ async interrupt(): Promise {
+ return new Promise((resolve, reject) => {
+ this.sendCommand("exec-interrupt").then((info) => {
+ resolve(info.getType() == "done");
+ }, reject);
+ });
+ }
+
+ async continue(reverse: boolean = false): Promise {
+ return new Promise((resolve, reject) => {
+ this.sendCommand("exec-continue" + (reverse ? " --reverse" : "")).then((info) => {
+ resolve(info.getType() == "running");
+ }, reject);
+ });
+ }
+
+ async next(reverse: boolean = false): Promise {
+ return new Promise((resolve, reject) => {
+ this.sendCliCommand("next").then((info) => {
+ resolve(info.getType() == "done");
+ }, reject);
+ });
+ }
+
+ async step(reverse: boolean = false): Promise {
+ return new Promise((resolve, reject) => {
+ this.sendCliCommand("step").then((info) => {
+ resolve(info.getType() == "done");
+ }, reject);
+ });
+ }
+
+ async stepOut(reverse: boolean = false): Promise {
+ return new Promise((resolve, reject) => {
+ this.sendCliCommand("finish").then((info) => {
+ resolve(info.getType() == "done");
+ }, reject);
+ });
+ }
+
+ async goto(filename: string, line: number): Promise {
+ return new Promise((resolve, reject) => {
+ const target: string = (filename ? '"' + escape(filename) + '":' : "") + line;
+ this.sendCliCommand("jump " + target).then(() => {
+ this.emit("step", undefined);
+ resolve(true);
+ }, reject);
+ });
+ }
+
+ async changeVariable(name: string, rawValue: string): Promise {
+ return this.sendCommand("gdb-set var " + name + "=" + rawValue);
+ }
+
+ async setBreakPointCondition(bkptNum, condition): Promise {
+ return this.sendCommand("break-condition " + bkptNum + " \"" + escape(condition) + "\" 1");
+ }
+
+ async setEntryBreakPoint(entryPoint: string): Promise {
+ return this.sendCommand("break-insert -t -f " + entryPoint);
+ }
+
+ async addBreakPoint(breakpoint: Breakpoint): Promise<[boolean, Breakpoint]> {
+ return new Promise((resolve, reject) => {
+ if (this.breakpoints.has(breakpoint))
+ return resolve([false, undefined]);
+ let locationOpt = "";
+ if (breakpoint.breakCountCondition) {
+ const numRegex = /\d+/;
+ if (breakpoint.breakCountCondition[0] == ">")
+ locationOpt += "-i " + numRegex.exec(breakpoint.breakCountCondition.substring(1))[0] + " ";
+ else {
+ const match = numRegex.exec(breakpoint.breakCountCondition)[0];
+ if (match.length != breakpoint.breakCountCondition.length) {
+ this.log("stderr", "Unsupported break count expression: '" + breakpoint.breakCountCondition + "'. Only supports 'X' for breaking once after X times or '>X' for ignoring the first X breaks");
+ locationOpt += "-t ";
+ } else if (parseInt(match) != 0)
+ locationOpt += "-t -i " + parseInt(match) + " ";
+ }
+ }
+ if (breakpoint.raw) {
+ locationOpt += '"' + escape(breakpoint.raw) + '"';
+ }
+ else {
+ locationOpt += `"${breakpoint.sourceFileName}:${breakpoint.lineNumber}"`;
+ }
+
+ // location="/home/user02/add_custom.cpp:31",前后带双引号
+ const locationArr = locationOpt.split('/');
+ let relativeLocaltion = locationArr[locationArr.length - 1];
+ // relativeLocaltion=add_custom.cpp:31",需要在前面追加一个双引号
+ relativeLocaltion = `"${relativeLocaltion}`;
+
+ this.sendCommand("break-insert -f " + relativeLocaltion).then((result) => {
+ if (result.getType() == "done") {
+ const breakPointNum = parseInt(result.getResult("bkpt")["number"]);
+ const newBreakPoint: Breakpoint = {
+ sourceFileName: breakpoint.sourceFileName ? breakpoint.sourceFileName : result.getResult("bkpt")["file"],
+ raw: breakpoint.raw,
+ lineNumber: parseInt(result.getResult("bkpt")["line"]),
+ breakCondition: breakpoint.breakCondition
+ };
+ if (breakpoint.breakCondition) {
+ this.setBreakPointCondition(breakPointNum, breakpoint.breakCondition).then((result) => {
+ if (result.getType() == "done") {
+ this.breakpoints.set(newBreakPoint, breakPointNum);
+ resolve([true, newBreakPoint]);
+ } else {
+ resolve([false, undefined]);
+ }
+ }, reject);
+ } else {
+ this.breakpoints.set(newBreakPoint, breakPointNum);
+ resolve([true, newBreakPoint]);
+ }
+ } else {
+ reject(result);
+ }
+ }, reject);
+ });
+ }
+
+ async clearBreakPoints(source?: string): Promise {
+ return new Promise((resolve, reject) => {
+ const promises = [];
+ const breakpoints = this.breakpoints;
+ this.breakpoints = new Map();
+ breakpoints.forEach((breakPointNumber, breakpoint) => {
+ if (breakpoint.sourceFileName === source) {
+ promises.push(this.sendCommand("break-delete " + breakPointNumber).then((result) => {
+ if (result.getType() == "done") resolve(true);
+ else resolve(false);
+ }));
+ } else {
+ this.breakpoints.set(breakpoint, breakPointNumber);
+ }
+ });
+ Promise.all(promises).then(resolve, reject);
+ });
+ }
+
+ async getThreadsInfo(): Promise {
+ const result = await this.sendCommand("thread-info");
+ const threads = result.getResult("threads");
+ return threads.map(element => {
+ const ret: ThreadInfo = {
+ id: parseInt(element["id"]),
+ targetId: element["target-id"]
+ };
+ return ret;
+ });
+ }
+
+ async getStackListFramesInfo(startFrame: number, maxLevels: number, thread: number): Promise {
+ const options: string[] = [];
+
+ if (thread != 0) {
+ options.push("--thread " + thread);
+ }
+
+ const depth: number = parseInt((await this.sendCommand(["stack-info-depth"].concat(options).join(" "))).getResult("depth"));
+ const lowFrame: number = startFrame ? startFrame : 0;
+ const highFrame: number = (maxLevels ? Math.min(depth, lowFrame + maxLevels) : depth) - 1;
+
+ if (highFrame < lowFrame) {
+ return [];
+ }
+
+ options.push(lowFrame.toString());
+ options.push(highFrame.toString());
+
+ const result = await this.sendCommand(["stack-list-frames"].concat(options).join(" "));
+ const stackFramesInfo = result.getResult("stack");
+ return stackFramesInfo.map(frameInfo => {
+ let frame = frameInfo[1];
+ const level = frame["level"];
+ const addr = frame["addr"];
+ const func = frame["func"];
+ const filename = frame["file"];
+ let fileFullName: string = frame["fullname"];
+ if (fileFullName) {
+ fileFullName = path.normalize(fileFullName);
+ }
+
+ let line = 0;
+ const lnstr = frame["line"];
+ if (lnstr)
+ line = parseInt(lnstr);
+ const from = parseInt(frame["from"]);
+ return {
+ pcAddr: addr,
+ fileName: filename,
+ fullFileName: fileFullName,
+ functionName: func || from,
+ frameNumber: level,
+ pcLineNumber: line
+ };
+ });
+ }
+
+ async getStackVariables(thread: number, frame: number): Promise {
+ const result = await this.sendCommand(`stack-list-variables --thread ${thread} --frame ${frame} --simple-values`);
+ return result;
+ }
+
+ isPointType(element: any) {
+ const type = element['type'];
+ return type.includes('*');
+ }
+
+ tmpProcessPointValue(ret: StackVariable[], element: any) {
+ let valueOfElement = element['value'];
+ if (valueOfElement) {
+ const regex = / "[^"]*"/g;
+ valueOfElement = valueOfElement.replace(/'/g, '"').replace(regex, "");
+ for (let i = 0; i < element.length; i++) {
+ if (element[i][0] === 'value') {
+ element[i][1] = valueOfElement;
+ }
+ }
+ }
+ const key = element['name'];
+ const value = element['value'];
+ const type = element['type'];
+ ret.push({
+ name: key,
+ value: value,
+ type: type,
+ raw: element
+ })
+ }
+
+ async getRegistersNames(): Promise {
+ let command = "data-list-register-names";
+ return await this.sendCommand(command);
+ }
+
+ async getRegistersValues(): Promise {
+ let command = "data-list-register-values x";
+ return await this.sendCommand(command);
+ }
+
+ async evalExpression(name: string, thread: number, frame: number): Promise {
+ let command = "data-evaluate-expression ";
+ if (thread != 0) {
+ command += `--thread ${thread} --frame ${frame} `;
+ }
+ command += name;
+ let evalExpressionResult = await this.sendCommand(command);
+ return evalExpressionResult;
+ }
+
+ async varListChildren(name: string): Promise {
+ const res = await this.sendCommand(`var-list-children --all-values ${this.quote(name)}`);
+ const children = res.getResult("children") || [];
+ const omg: VariableObjectChild[] = children.map(child => new VariableObjectChild(child[1]));
+ return omg;
+ }
+
+ log(type: string, msg: string, newLine: boolean = true) {
+ // 屏蔽添加删除断点会打印异常信息
+ if (msg?.includes('failed to set breakpoint site at')) {
+ return;
+ }
+
+ let msgOutput = msg.replace(/\\{1,3}[trn]/g, '');
+ if (newLine) {
+ msgOutput += "\n";
+ }
+ this.emit("output", type, msgOutput);
+ }
+
+ async sendUserInput(command: string, threadId: number = 0, frameLevel: number = 0): Promise {
+ if (command.startsWith("-")) {
+ return this.sendCommand(command.substring(1));
+ } else {
+ return this.sendCliCommand(command, threadId, frameLevel, true);
+ }
+ }
+
+ async readMemoryRequest(memoryReference:MemoryReference, offset: number, count: number): Promise {
+ return new Promise((resolve, reject) => { })
+ }
+
+ sendRaw(raw: string, token:number = undefined) {
+ if (this.printMiInput) {
+ this.log("console", `MI Input: ${raw}`);
+ }
+ this.process.stdin.write(raw + "\n");
+ }
+
+ async sendCliCommand(command: string, threadId: number = 0, frameLevel: number = 0, isUserInput: boolean = false): Promise {
+ let miCommand = "interpreter-exec ";
+ miCommand += `command "${command.replace(/[\\"']/g, '\\$&')}"`;
+ return this.sendCommand(miCommand, isUserInput);
+ }
+
+ async sendCommand(command: string, isUserInput: boolean = false): Promise {
+ const sel = this.currentToken++;
+ return new Promise((resolve, reject) => {
+ this.handlers[sel] = (node: ResultRecord) => {
+ if (node && node.getType() == ResultRecordType.ERROR) {
+ reject(new Error(node.response));
+ } else {
+ resolve(node);
+ }
+ };
+ if (isUserInput) {
+ this.userInputCmdTokens.add(sel);
+ }
+ this.sendRaw(sel + "-" + command, sel);
+ });
+ }
+
+ isReady(): boolean {
+ return !!this.process;
+ }
+
+ protected quote(text: string): string {
+ return /^-|[^\w\d\/_\-\.]/g.test(text) ? ('"' + escape(text) + '"') : text;
+ }
+
+ printMiInput: boolean;
+ printMiOutput: boolean;
+ targetArgs:string[];
+ userInputCmdTokens = new Set();
+ features: string[];
+ public envs: any;
+ private miParser: MIParser;
+ protected currentToken: number = 1;
+ protected handlers: { [index: number]: (info: OutputRecord) => any } = {};
+ protected breakpoints: Map = new Map();
+ protected outBuffer: string;
+ protected errbuf: string = '';
+ protected process: ChildProcess.ChildProcess;
+ protected stream;
+}
+
+export function execCmd(cmd:string):Promise {
+ return new Promise((resolve, reject) => {
+ exec(cmd, (error, stdout, stderr) => {
+ if (error) {
+ reject(error);
+ } else{
+ resolve(stdout);
+ }
+ })
+ });
+}
+
+
+export async function getMsdebugMiPath(sourceMsdebugMiPath: string, envs: string[]): Promise {
+ if (sourceMsdebugMiPath != undefined && !validatePath(sourceMsdebugMiPath, await getUserHomePath(), '/usr')) {
+ throw new Error(`Invalid path for msdebugMiPath. msdebugMiPath=${sourceMsdebugMiPath}`);
+ }
+
+ let targetMiPath = sourceMsdebugMiPath;
+ if (sourceMsdebugMiPath == undefined && envs['ASCEND_TOOLKIT_HOME'] != undefined) {
+ targetMiPath = `${envs['ASCEND_TOOLKIT_HOME']}/tools/msdebug/bin/msdebug-mi`;
+ }
+ return targetMiPath;
+}
+
+
+export async function getUserHomePath(): Promise {
+ let homePath = await execCmd('echo $HOME').catch(err => {throw err});
+ homePath = (homePath.trim() == '') ? '/' : homePath.replace(/\n/g, '');
+ return homePath;
+}
diff --git a/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/machine_interface/msdebug_mi.ts b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/machine_interface/msdebug_mi.ts
new file mode 100644
index 0000000000000000000000000000000000000000..71df93336c9c6a1ac6db8f899e4307fce4b3ae4e
--- /dev/null
+++ b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/machine_interface/msdebug_mi.ts
@@ -0,0 +1,142 @@
+/**
+ * Copyright (c) 2024 Huawei Technologies Co., Ltd.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import { MIBase } from "./mi_base";
+import backendGlobal from '../utils/backend_global';
+import { MemoryReference } from "../debug_session/memory";
+
+export class MsdebugMI extends MIBase {
+
+ async readMemoryRequest(memoryReference:MemoryReference, offset: number, count: number): Promise {
+ if (this.isHostState() || (!this.isHostState() && memoryReference.memoryLocation == 'COMMON')) {
+ return this.examineMemory4Host(parseInt(memoryReference.address), offset, count, memoryReference);
+ }
+ if (memoryReference.dataType == 'char[]') {
+ memoryReference.dataType = 'uint8_t[]';
+ const result = await this.examineMemory4Kernel(memoryReference, offset, count).then((res) => {
+ const arr = res.split(' ')
+ // 内存值转成字符串后,可能为空格,故不用空格分隔
+ return arr.map((item)=>String.fromCharCode(parseInt(`0x${item}`)));
+ })
+ memoryReference.dataType = 'char[]';
+ return result;
+ }
+
+ return this.examineMemory4Kernel(memoryReference, offset, count);
+
+ }
+
+ async examineMemory4Host(originalAddress: number, offset: number, count: number, memoryReference:any): Promise {
+ let address = updateAddress(originalAddress, offset, 16);
+ return new Promise((resolve, reject) => {
+ this.sendCliCommand(`x/${count}xb ${address} --force`).then((result) => {
+ resolve(this.parseExmaineMemoryCLIResultToStr(result.response, memoryReference));
+ }, reject);
+ });
+ }
+
+ async examineMemory4Kernel(memoryReference:MemoryReference, offset: number, count: number): Promise {
+ let originalAddress:number = parseInt(memoryReference.address);
+ let address: string;
+
+ if (memoryReference.memoryLocation == 'UB') {
+ address = updateAddress(originalAddress, offset, 10);
+ } else {
+ address = updateAddress(originalAddress, offset, 16);
+ }
+
+ let querySize = Math.min(count, parseInt(memoryReference.dataLength) - offset);
+
+ let cmd;
+ if (memoryReference.dataType == 'bool') {
+ cmd = `x -m ${memoryReference.memoryLocation} -f ${memoryReference.dataType} ${address} -s 1 -c ${querySize}`;
+ } else {
+ cmd = `x -m ${memoryReference.memoryLocation} -f ${memoryReference.dataType} ${address} -s ${querySize} -c 1`;
+ }
+
+ if (parseInt(memoryReference.dataLength) > 1024) {
+ cmd += ' --force';
+ }
+
+ return new Promise((resolve, reject) => {
+ this.sendCliCommand(cmd)
+ .then((result) => {
+ resolve(this.parseExmaineMemoryCLIResultToStr(result.getResult('result'), memoryReference));
+ }, reject);
+ });
+ }
+
+ isHostState(): boolean {
+ return !backendGlobal.kernel.isNpu;
+ }
+
+ parseExmaineMemoryCLIResultToStr(input: string, memoryReference:any): string {
+ if (input == undefined || input.length == 0) {
+ return '';
+ }
+ if (this.isHostState() || memoryReference.memoryLocation == 'COMMON') {
+ return this.parseMemoryToStrWhenHostState(input);
+ }
+ if (memoryReference.dataType == 'bool') {
+ return this.parseMemoryToStrWhenKernelState4Bool(input, memoryReference.memoryLocation);
+ }
+ return this.parseMemoryToStrWhenKernelState4Uint8(input, memoryReference.memoryLocation);
+ }
+
+ parseMemoryToStrWhenHostState(input: string): string {
+ const parts = input.split(/ |\n/);
+ const hexRegx = new RegExp('^0x[\\da-f]{2}$');
+ return parts.filter(part=> hexRegx.test(part)).map(part=>part.slice(2)).join(' ');
+ }
+
+ parseMemoryToStrWhenKernelState4Hex(input: string, memoryLocation: string): string {
+ let regex;
+ let from;
+ if (memoryLocation == 'UB') {
+ regex = /^0x[0-9a-f]{8}: 0x[0-9a-f]+/;
+ from = 14;
+ } else {
+ regex = /^0x[0-9a-f]{12}: 0x[0-9a-f]+/;
+ from = 18;
+ }
+ if (input.match(regex)) {
+ return input.substring(from, input.length - 1);
+ }
+ return input;
+ }
+
+ parseMemoryToStrWhenKernelState4Uint8(input: string, memoryLocation: string): string {
+ const firstColonIdx = input.indexOf(':');
+ const regex = new RegExp(`^0x[0-9a-f]{${firstColonIdx - 2}}:\\s\\{.*\\}`);
+ const from = firstColonIdx + 3
+ const end = input.length - 3;
+ let ret = input;
+ if (input.match(regex)) {
+ let hexAndSpaceStr = input.substring(from, end);
+ ret = hexAndSpaceStr.replace(/0x/g, '');
+ }
+ return ret;
+ }
+
+ parseMemoryToStrWhenKernelState4Bool(input: string, memoryLocation: string): string {
+ const arr = input.split(' ');
+ const hexRegx = new RegExp('true|false')
+ return arr.filter(str=>hexRegx.test(str)).map(str=> str.startsWith('true')?'true':'false').join(' ');
+ }
+}
+
+function updateAddress(address: number, offset: number, addressNumberSystem: number): string {
+ let res: string;
+ if (addressNumberSystem == 16) {
+ res = '0x' + (address + offset).toString(16).padStart(16, '0');
+ } else if (addressNumberSystem == 10) {
+ res = address + offset + '';
+ } else {
+ throw new Error('Not support.');
+ }
+ return res;
+}
\ No newline at end of file
diff --git a/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/machine_interface/process_env.ts b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/machine_interface/process_env.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f1791ef4a549b4c36915b2dc65d6f018788e7b8e
--- /dev/null
+++ b/plugins/mindstudio-vscode-plugins/mindstudio-debug-vscode-plugin/vscode-msdebug/src/machine_interface/process_env.ts
@@ -0,0 +1,209 @@
+/**
+ * Copyright (c) 2024 Huawei Technologies Co., Ltd.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import * as fs from "fs";
+import * as path from "path";
+import {readFileContent} from "../utils/file_util";
+
+/**
+ * 替换用户输入的环境变量$VAR、${VAR}
+ * @param envs 用户配置的环境变量, 可能含有$VAR、${VAR}
+ * @param basicEnv 基础环境变量
+ * @param isEnvScript 是否处理environ
+ * @returns
+ */
+function replaceEnvVariable(envs: Map[], retMap: Map, isEnvScript: boolean): Map {
+ for (let env of envs) {
+ if (!env.has("name") || !env.has("value")) {
+ // 环境变量格式不对
+ if (isEnvScript) {
+ throw new Error(`environmentScript found bad format: ${env}`);
+ }
+ else {
+ throw new Error(`environment bad format: ${env} , key must be name and value, found in launch.json`);
+ }
+
+ }
+
+ let name = env.get("name");
+ let value = env.get("value").trim();
+
+ let valueList = value.split(":");
+ let resultList = [];
+ for (let vl of valueList) {
+ let valueListList = vl.split("/");
+ let resultListList = [];
+ for (let vll of valueListList) {
+ vll = vll.trim();
+
+ let vllPure = "";
+ let isEnv = false;
+ if (vll.match(/^\${(.+)}$/)) {
+ // 环境变量有大括号
+ vllPure = vll.match(/^\${(.+)}$/)[1];
+ isEnv = true;
+ }
+ else if (vll.match(/^\$(.+)$/)) {
+ // 环境变量没有大括号
+ vllPure = vll.match(/^\$(.+)$/)[1];
+ isEnv = true;
+ }
+ else {
+ vllPure = vll;
+ isEnv = false;
+ }
+
+ if (isEnv) {
+ if (retMap.has(vllPure)) {
+ // 已有环境变量中存在该名称, 进行替换;找不到不做添加,相当于空
+ resultListList.push(retMap.get(vllPure));
+ }
+ }
+ else {
+ // 不是环境变量,原样添加
+ resultListList.push(vllPure);
+ }
+ }
+
+ if (resultListList.length > 0) {
+ resultList.push(resultListList.join("/"));
+ }
+ }
+ retMap.set(name, resultList.join(":"));
+ }
+
+ return retMap;
+}
+
+/**
+ * 读取环境变量文件
+ * @param envFiles 用户配置的环境变量文件
+ * @returns
+ */
+function readEnvFile(envFiles: string[]): Map