debug_test.go 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610
  1. /*
  2. * ECAL
  3. *
  4. * Copyright 2020 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the MIT
  7. * License, If a copy of the MIT License was not distributed with this
  8. * file, You can obtain one at https://opensource.org/licenses/MIT.
  9. */
  10. package interpreter
  11. import (
  12. "encoding/json"
  13. "fmt"
  14. "strconv"
  15. "strings"
  16. "sync"
  17. "testing"
  18. "time"
  19. "devt.de/krotik/common/errorutil"
  20. "devt.de/krotik/ecal/scope"
  21. "devt.de/krotik/ecal/util"
  22. )
  23. func TestSimpleDebugging(t *testing.T) {
  24. var err error
  25. defer func() {
  26. testDebugger = nil
  27. }()
  28. testDebugger = NewECALDebugger(nil)
  29. _, err = testDebugger.HandleInput("break ECALEvalTest:3")
  30. errorutil.AssertOk(err)
  31. _, err = testDebugger.HandleInput("break ECALEvalTest:4")
  32. errorutil.AssertOk(err)
  33. _, err = testDebugger.HandleInput("disablebreak ECALEvalTest:4")
  34. errorutil.AssertOk(err)
  35. wg := &sync.WaitGroup{}
  36. wg.Add(1)
  37. var tid uint64
  38. go func() {
  39. _, err = UnitTestEval(`
  40. log("test1")
  41. log("test2")
  42. log("test3")
  43. `, nil)
  44. if err != nil {
  45. t.Error(err)
  46. }
  47. testDebugger.RecordThreadFinished(tid)
  48. wg.Done()
  49. }()
  50. tid = waitForThreadSuspension(t)
  51. out, err := testDebugger.HandleInput(fmt.Sprintf("status"))
  52. outBytes, _ := json.MarshalIndent(out, "", " ")
  53. outString := string(outBytes)
  54. if err != nil || outString != `{
  55. "breakonstart": false,
  56. "breakpoints": {
  57. "ECALEvalTest:3": true,
  58. "ECALEvalTest:4": false
  59. },
  60. "sources": [
  61. "ECALEvalTest"
  62. ],
  63. "threads": {
  64. "1": {
  65. "callStack": [],
  66. "error": null,
  67. "threadRunning": false
  68. }
  69. }
  70. }` {
  71. t.Error("Unexpected result:", outString, err)
  72. return
  73. }
  74. out, err = testDebugger.HandleInput(fmt.Sprintf("describe %v", tid))
  75. outBytes, _ = json.MarshalIndent(out, "", " ")
  76. outString = string(outBytes)
  77. if err != nil || outString != `{
  78. "callStack": [],
  79. "callStackNode": [],
  80. "callStackVsSnapshot": [],
  81. "callStackVsSnapshotGlobal": [],
  82. "code": "log(\"test2\")",
  83. "error": null,
  84. "node": {
  85. "allowescapes": false,
  86. "children": [
  87. {
  88. "children": [
  89. {
  90. "allowescapes": true,
  91. "id": 5,
  92. "identifier": false,
  93. "line": 3,
  94. "linepos": 5,
  95. "name": "string",
  96. "pos": 18,
  97. "source": "ECALEvalTest",
  98. "value": "test2"
  99. }
  100. ],
  101. "name": "funccall"
  102. }
  103. ],
  104. "id": 7,
  105. "identifier": true,
  106. "line": 3,
  107. "linepos": 1,
  108. "name": "identifier",
  109. "pos": 14,
  110. "source": "ECALEvalTest",
  111. "value": "log"
  112. },
  113. "threadRunning": false,
  114. "vs": {},
  115. "vsGlobal": {}
  116. }` {
  117. t.Error("Unexpected result:", outString, err)
  118. return
  119. }
  120. // Continue until the end
  121. _, err = testDebugger.HandleInput(fmt.Sprintf("cont %v Resume", tid))
  122. errorutil.AssertOk(err)
  123. wg.Wait()
  124. if err != nil || testlogger.String() != `
  125. test1
  126. test2
  127. test3`[1:] {
  128. t.Error("Unexpected result:", testlogger.String(), err)
  129. return
  130. }
  131. _, err = testDebugger.HandleInput("rmbreak ECALEvalTest:4")
  132. errorutil.AssertOk(err)
  133. out, err = testDebugger.HandleInput(fmt.Sprintf("status"))
  134. outBytes, _ = json.MarshalIndent(out, "", " ")
  135. outString = string(outBytes)
  136. if err != nil || outString != `{
  137. "breakonstart": false,
  138. "breakpoints": {
  139. "ECALEvalTest:3": true
  140. },
  141. "sources": [
  142. "ECALEvalTest"
  143. ],
  144. "threads": {}
  145. }` {
  146. t.Error("Unexpected result:", outString, err)
  147. return
  148. }
  149. _, err = testDebugger.HandleInput("break ECALEvalTest:4")
  150. errorutil.AssertOk(err)
  151. _, err = testDebugger.HandleInput("rmbreak ECALEvalTest")
  152. errorutil.AssertOk(err)
  153. out, err = testDebugger.HandleInput(fmt.Sprintf("status"))
  154. outBytes, _ = json.MarshalIndent(out, "", " ")
  155. outString = string(outBytes)
  156. if err != nil || outString != `{
  157. "breakonstart": false,
  158. "breakpoints": {},
  159. "sources": [
  160. "ECALEvalTest"
  161. ],
  162. "threads": {}
  163. }` {
  164. t.Error("Unexpected result:", outString, err)
  165. return
  166. }
  167. }
  168. func TestDebugReset(t *testing.T) {
  169. var err error
  170. defer func() {
  171. testDebugger = nil
  172. }()
  173. testDebugger = NewECALDebugger(nil)
  174. if _, err = testDebugger.HandleInput("break ECALEvalTest:3"); err != nil {
  175. t.Error("Unexpected result:", err)
  176. return
  177. }
  178. wg := &sync.WaitGroup{}
  179. wg.Add(1)
  180. go func() {
  181. defer wg.Done()
  182. _, err = UnitTestEval(`
  183. log("test1")
  184. log("test2")
  185. log("test3")
  186. `, nil)
  187. if err != nil {
  188. t.Error(err)
  189. }
  190. }()
  191. waitForThreadSuspension(t)
  192. out, err := testDebugger.HandleInput(fmt.Sprintf("status"))
  193. outBytes, _ := json.MarshalIndent(out, "", " ")
  194. outString := string(outBytes)
  195. if err != nil || outString != `{
  196. "breakonstart": false,
  197. "breakpoints": {
  198. "ECALEvalTest:3": true
  199. },
  200. "sources": [
  201. "ECALEvalTest"
  202. ],
  203. "threads": {
  204. "1": {
  205. "callStack": [],
  206. "error": null,
  207. "threadRunning": false
  208. }
  209. }
  210. }` {
  211. t.Error("Unexpected result:", outString, err)
  212. return
  213. }
  214. testDebugger.StopThreads(100 * time.Millisecond)
  215. wg.Wait()
  216. if err != nil || testlogger.String() != `
  217. test1
  218. test2`[1:] {
  219. t.Error("Unexpected result:", testlogger.String(), err)
  220. return
  221. }
  222. }
  223. func TestErrorStop(t *testing.T) {
  224. var err, evalError error
  225. defer func() {
  226. testDebugger = nil
  227. }()
  228. testDebugger = NewECALDebugger(nil)
  229. testDebugger.BreakOnError(true)
  230. if _, err = testDebugger.HandleInput("break ECALEvalTest:8"); err != nil {
  231. t.Error("Unexpected result:", err)
  232. return
  233. }
  234. wg := &sync.WaitGroup{}
  235. wg.Add(1)
  236. go func() {
  237. defer wg.Done()
  238. _, evalError = UnitTestEval(`
  239. func err () {
  240. raise("foo")
  241. }
  242. log("test1")
  243. log("test2")
  244. err()
  245. log("test3")
  246. `, nil)
  247. }()
  248. waitForThreadSuspension(t)
  249. out, err := testDebugger.HandleInput(fmt.Sprintf("status"))
  250. outBytes, _ := json.MarshalIndent(out, "", " ")
  251. outString := string(outBytes)
  252. if err != nil || outString != `{
  253. "breakonstart": false,
  254. "breakpoints": {
  255. "ECALEvalTest:8": true
  256. },
  257. "sources": [
  258. "ECALEvalTest"
  259. ],
  260. "threads": {
  261. "1": {
  262. "callStack": [
  263. "err() (ECALEvalTest:7)"
  264. ],
  265. "error": {
  266. "Data": null,
  267. "Detail": "",
  268. "Environment": {},
  269. "Node": {
  270. "Name": "identifier",
  271. "Token": {
  272. "ID": 7,
  273. "Pos": 16,
  274. "Val": "raise",
  275. "Identifier": true,
  276. "AllowEscapes": false,
  277. "PrefixNewlines": 1,
  278. "Lsource": "ECALEvalTest",
  279. "Lline": 3,
  280. "Lpos": 2
  281. },
  282. "Meta": null,
  283. "Children": [
  284. {
  285. "Name": "funccall",
  286. "Token": null,
  287. "Meta": null,
  288. "Children": [
  289. {
  290. "Name": "string",
  291. "Token": {
  292. "ID": 5,
  293. "Pos": 22,
  294. "Val": "foo",
  295. "Identifier": false,
  296. "AllowEscapes": true,
  297. "PrefixNewlines": 0,
  298. "Lsource": "ECALEvalTest",
  299. "Lline": 3,
  300. "Lpos": 8
  301. },
  302. "Meta": null,
  303. "Children": [],
  304. "Runtime": {}
  305. }
  306. ],
  307. "Runtime": {}
  308. }
  309. ],
  310. "Runtime": {}
  311. },
  312. "Source": "ECALTestRuntime (ECALEvalTest)",
  313. "Trace": null,
  314. "Type": "foo"
  315. },
  316. "threadRunning": false
  317. }
  318. }
  319. }` {
  320. t.Error("Unexpected result:", outString, err)
  321. return
  322. }
  323. if _, err = testDebugger.HandleInput(fmt.Sprintf("cont 1 Resume")); err != nil {
  324. t.Error("Unexpected result:", err)
  325. return
  326. }
  327. wg.Wait()
  328. if evalError == nil || testlogger.String() != `
  329. test1
  330. test2`[1:] || evalError.Error() != "ECAL error in ECALTestRuntime (ECALEvalTest): foo () (Line:3 Pos:2)" {
  331. t.Error("Unexpected result:", testlogger.String(), evalError, err)
  332. return
  333. }
  334. }
  335. func TestConcurrentDebugging(t *testing.T) {
  336. var err error
  337. defer func() {
  338. testDebugger = nil
  339. }()
  340. testDebugger = NewECALDebugger(nil)
  341. if _, err = testDebugger.HandleInput("break ECALEvalTest:5"); err != nil {
  342. t.Error("Unexpected result:", err)
  343. return
  344. }
  345. wg := &sync.WaitGroup{}
  346. wg.Add(2)
  347. erp := NewECALRuntimeProvider("ECALTestRuntime", nil, nil)
  348. vs := scope.NewScope(scope.GlobalScope)
  349. go func() {
  350. _, err = UnitTestEvalWithRuntimeProvider(`
  351. a := 1
  352. b := 1
  353. func test1() {
  354. log("test3")
  355. b := a + 1
  356. }
  357. log("test1")
  358. log("test2")
  359. test1()
  360. log("test4")
  361. `, vs, erp)
  362. if err != nil {
  363. t.Error(err)
  364. }
  365. wg.Done()
  366. }()
  367. go func() {
  368. _, err = UnitTestEvalWithRuntimeProvider(`
  369. a := 1
  370. c := 1
  371. func test2() {
  372. log("test3")
  373. c := a + 1
  374. }
  375. log("test1")
  376. log("test2")
  377. test2()
  378. log("test4")
  379. mutex a { mutex a { log("test5") } }
  380. `, vs, erp)
  381. if err != nil {
  382. t.Error(err)
  383. }
  384. wg.Done()
  385. }()
  386. waitForAllThreadSuspension(t)
  387. out, err := testDebugger.HandleInput(fmt.Sprintf("status"))
  388. outBytes, _ := json.MarshalIndent(out, "", " ")
  389. outString := string(outBytes)
  390. if err != nil || (outString != `{
  391. "breakonstart": false,
  392. "breakpoints": {
  393. "ECALEvalTest:5": true
  394. },
  395. "sources": [
  396. "ECALEvalTest"
  397. ],
  398. "threads": {
  399. "1": {
  400. "callStack": [
  401. "test1() (ECALEvalTest:10)"
  402. ],
  403. "error": null,
  404. "threadRunning": false
  405. },
  406. "2": {
  407. "callStack": [
  408. "test2() (ECALEvalTest:10)"
  409. ],
  410. "error": null,
  411. "threadRunning": false
  412. }
  413. }
  414. }` && outString != `{
  415. "breakonstart": false,
  416. "breakpoints": {
  417. "ECALEvalTest:5": true
  418. },
  419. "sources": [
  420. "ECALEvalTest"
  421. ],
  422. "threads": {
  423. "1": {
  424. "callStack": [
  425. "test2() (ECALEvalTest:10)"
  426. ],
  427. "error": null,
  428. "threadRunning": false
  429. },
  430. "2": {
  431. "callStack": [
  432. "test1() (ECALEvalTest:10)"
  433. ],
  434. "error": null,
  435. "threadRunning": false
  436. }
  437. }
  438. }`) {
  439. t.Error("Unexpected result:", outString, err)
  440. return
  441. }
  442. ls, err := testDebugger.HandleInput(fmt.Sprintf("lockstate"))
  443. lsBytes, _ := json.MarshalIndent(ls, "", " ")
  444. lsString := string(lsBytes)
  445. if lsString != `{
  446. "log": [],
  447. "owners": {},
  448. "threads": {
  449. "IdleWorkerThreads": null,
  450. "TaskQueueSize": 0,
  451. "TotalWorkerThreads": null
  452. }
  453. }` {
  454. t.Error("Unexpected result:", lsString)
  455. return
  456. }
  457. // Continue until the end
  458. if _, err := testDebugger.HandleInput(fmt.Sprintf("cont 1 Resume")); err != nil {
  459. t.Error("Unexpected result:", err)
  460. return
  461. }
  462. if _, err := testDebugger.HandleInput(fmt.Sprintf("cont 2 Resume")); err != nil {
  463. t.Error("Unexpected result:", err)
  464. return
  465. }
  466. wg.Wait()
  467. if vs.String() != `GlobalScope {
  468. a (float64) : 1
  469. b (float64) : 2
  470. c (float64) : 2
  471. test1 (*interpreter.function) : ecal.function: test1 (Line 4, Pos 1)
  472. test2 (*interpreter.function) : ecal.function: test2 (Line 4, Pos 1)
  473. block: mutex (Line:12 Pos:1) {
  474. block: mutex (Line:12 Pos:11) {
  475. }
  476. }
  477. }` {
  478. t.Error("Unexpected result:", vs)
  479. return
  480. }
  481. ls, err = testDebugger.HandleInput(fmt.Sprintf("lockstate"))
  482. lsBytes, _ = json.MarshalIndent(ls, "", " ")
  483. lsString = string(lsBytes)
  484. if !strings.Contains(lsString, "took lock a with owner") || !strings.Contains(lsString, "attempted to take lock a twice") {
  485. t.Error("Unexpected result:", lsString)
  486. return
  487. }
  488. }
  489. func waitForThreadSuspension(t *testing.T) uint64 {
  490. var tid uint64
  491. for i := 0; i < 100; i++ {
  492. state, err := testDebugger.HandleInput("status")
  493. errorutil.AssertOk(err)
  494. threads := state.(map[string]interface{})["threads"].(map[string]map[string]interface{})
  495. if len(threads) > 0 {
  496. for threadID, status := range threads {
  497. if r, ok := status["threadRunning"]; ok && !r.(bool) {
  498. threadIDNum, _ := strconv.ParseInt(threadID, 10, 0)
  499. tid = uint64(threadIDNum)
  500. return tid
  501. }
  502. }
  503. }
  504. time.Sleep(1 * time.Millisecond)
  505. }
  506. panic("No suspended thread")
  507. }
  508. func waitForAllThreadSuspension(t *testing.T) uint64 {
  509. var tid uint64
  510. for i := 0; i < 100; i++ {
  511. state, err := testDebugger.HandleInput("status")
  512. errorutil.AssertOk(err)
  513. threads := state.(map[string]interface{})["threads"].(map[string]map[string]interface{})
  514. if len(threads) > 0 {
  515. allSuspended := true
  516. for _, status := range threads {
  517. if r, ok := status["threadRunning"]; ok && !r.(bool) {
  518. allSuspended = false
  519. break
  520. }
  521. }
  522. if allSuspended {
  523. break
  524. }
  525. }
  526. time.Sleep(1 * time.Millisecond)
  527. }
  528. return tid
  529. }
  530. func TestStepDebugging(t *testing.T) {
  531. var err error
  532. defer func() {
  533. testDebugger = nil
  534. }()
  535. testDebugger = NewECALDebugger(nil)
  536. code := `
  537. log("start")
  538. func fa(x) {
  539. a := 1
  540. log("a enter")
  541. fb(x)
  542. log("a exit")
  543. }
  544. func fb(x) {
  545. b := 2
  546. log("b enter")
  547. fc()
  548. fc(fc())
  549. log("b exit")
  550. }
  551. func fc() {
  552. c := 3
  553. log("c enter")
  554. log("c exit")
  555. }
  556. fa(1)
  557. func e() {
  558. log("e()")
  559. }
  560. func d() {
  561. e()
  562. }
  563. d(d())
  564. log("finish")
  565. `
  566. _, err = testDebugger.HandleInput("break ECALEvalTest:10")
  567. errorutil.AssertOk(err)
  568. _, err = testDebugger.HandleInput("breakonstart true")
  569. errorutil.AssertOk(err)
  570. wg := &sync.WaitGroup{}
  571. wg.Add(1)
  572. go func() {
  573. _, err = UnitTestEval(code, nil)
  574. if err != nil {
  575. t.Error(err)
  576. }
  577. wg.Done()
  578. }()
  579. tid := waitForThreadSuspension(t)
  580. if state := getDebuggerState(tid, t); state != `{
  581. "breakpoints": {
  582. "ECALEvalTest:10": true
  583. },
  584. "code": "log(\"start\")",
  585. "threads": {
  586. "1": {
  587. "callStack": [],
  588. "error": null,
  589. "threadRunning": false
  590. }
  591. },
  592. "vs": {}
  593. }` {
  594. t.Error("Unexpected state:", state)
  595. return
  596. }
  597. _, err = testDebugger.HandleInput(fmt.Sprintf("cont %v resume", tid))
  598. errorutil.AssertOk(err)
  599. tid = waitForThreadSuspension(t)
  600. if state := getDebuggerState(tid, t); state != `{
  601. "breakpoints": {
  602. "ECALEvalTest:10": true
  603. },
  604. "code": "b := 2",
  605. "threads": {
  606. "1": {
  607. "callStack": [
  608. "fa(1) (ECALEvalTest:21)",
  609. "fb(x) (ECALEvalTest:6)"
  610. ],
  611. "error": null,
  612. "threadRunning": false
  613. }
  614. },
  615. "vs": {
  616. "x": 1
  617. }
  618. }` {
  619. t.Error("Unexpected state:", state)
  620. return
  621. }
  622. // Step in without a function
  623. _, err = testDebugger.HandleInput(fmt.Sprintf("cont %v stepin", tid))
  624. errorutil.AssertOk(err)
  625. tid = waitForThreadSuspension(t)
  626. if state := getDebuggerState(tid, t); state != `{
  627. "breakpoints": {
  628. "ECALEvalTest:10": true
  629. },
  630. "code": "log(\"b enter\")",
  631. "threads": {
  632. "1": {
  633. "callStack": [
  634. "fa(1) (ECALEvalTest:21)",
  635. "fb(x) (ECALEvalTest:6)"
  636. ],
  637. "error": null,
  638. "threadRunning": false
  639. }
  640. },
  641. "vs": {
  642. "b": 2,
  643. "x": 1
  644. }
  645. }` {
  646. t.Error("Unexpected state:", state)
  647. return
  648. }
  649. // Normal step over
  650. _, err = testDebugger.HandleInput(fmt.Sprintf("cont %v stepover", tid))
  651. errorutil.AssertOk(err)
  652. tid = waitForThreadSuspension(t)
  653. if state := getDebuggerState(tid, t); state != `{
  654. "breakpoints": {
  655. "ECALEvalTest:10": true
  656. },
  657. "code": "fc()",
  658. "threads": {
  659. "1": {
  660. "callStack": [
  661. "fa(1) (ECALEvalTest:21)",
  662. "fb(x) (ECALEvalTest:6)"
  663. ],
  664. "error": null,
  665. "threadRunning": false
  666. }
  667. },
  668. "vs": {
  669. "b": 2,
  670. "x": 1
  671. }
  672. }` {
  673. t.Error("Unexpected state:", state)
  674. return
  675. }
  676. // Normal step in
  677. _, err = testDebugger.HandleInput(fmt.Sprintf("cont %v stepin", tid))
  678. errorutil.AssertOk(err)
  679. tid = waitForThreadSuspension(t)
  680. if state := getDebuggerState(tid, t); state != `{
  681. "breakpoints": {
  682. "ECALEvalTest:10": true
  683. },
  684. "code": "c := 3",
  685. "threads": {
  686. "1": {
  687. "callStack": [
  688. "fa(1) (ECALEvalTest:21)",
  689. "fb(x) (ECALEvalTest:6)",
  690. "fc() (ECALEvalTest:12)"
  691. ],
  692. "error": null,
  693. "threadRunning": false
  694. }
  695. },
  696. "vs": {}
  697. }` {
  698. t.Error("Unexpected state:", state)
  699. return
  700. }
  701. // Normal step out
  702. _, err = testDebugger.HandleInput(fmt.Sprintf("cont %v stepout", tid))
  703. errorutil.AssertOk(err)
  704. tid = waitForThreadSuspension(t)
  705. if state := getDebuggerState(tid, t); state != `{
  706. "breakpoints": {
  707. "ECALEvalTest:10": true
  708. },
  709. "code": "fc(fc())",
  710. "threads": {
  711. "1": {
  712. "callStack": [
  713. "fa(1) (ECALEvalTest:21)",
  714. "fb(x) (ECALEvalTest:6)"
  715. ],
  716. "error": null,
  717. "threadRunning": false
  718. }
  719. },
  720. "vs": {
  721. "b": 2,
  722. "x": 1
  723. }
  724. }` {
  725. t.Error("Unexpected state:", state)
  726. return
  727. }
  728. // Step in and step out - we should end up on the same line as before
  729. _, err = testDebugger.HandleInput(fmt.Sprintf("cont %v stepin", tid))
  730. errorutil.AssertOk(err)
  731. testStepDebugging2(t, testDebugger, wg)
  732. }
  733. func testStepDebugging2(t *testing.T, testDebugger util.ECALDebugger, wg *sync.WaitGroup) {
  734. tid := waitForThreadSuspension(t)
  735. if state := getDebuggerState(tid, t); state != `{
  736. "breakpoints": {
  737. "ECALEvalTest:10": true
  738. },
  739. "code": "c := 3",
  740. "threads": {
  741. "1": {
  742. "callStack": [
  743. "fa(1) (ECALEvalTest:21)",
  744. "fb(x) (ECALEvalTest:6)",
  745. "fc() (ECALEvalTest:13)"
  746. ],
  747. "error": null,
  748. "threadRunning": false
  749. }
  750. },
  751. "vs": {}
  752. }` {
  753. t.Error("Unexpected state:", state)
  754. return
  755. }
  756. _, err := testDebugger.HandleInput(fmt.Sprintf("cont %v stepout", tid))
  757. errorutil.AssertOk(err)
  758. tid = waitForThreadSuspension(t)
  759. if state := getDebuggerState(tid, t); state != `{
  760. "breakpoints": {
  761. "ECALEvalTest:10": true
  762. },
  763. "code": "fc(fc())",
  764. "threads": {
  765. "1": {
  766. "callStack": [
  767. "fa(1) (ECALEvalTest:21)",
  768. "fb(x) (ECALEvalTest:6)"
  769. ],
  770. "error": null,
  771. "threadRunning": false
  772. }
  773. },
  774. "vs": {
  775. "b": 2,
  776. "x": 1
  777. }
  778. }` {
  779. t.Error("Unexpected state:", state)
  780. return
  781. }
  782. // Normal step out
  783. _, err = testDebugger.HandleInput(fmt.Sprintf("cont %v stepout", tid))
  784. errorutil.AssertOk(err)
  785. tid = waitForThreadSuspension(t)
  786. if state := getDebuggerState(tid, t); state != `{
  787. "breakpoints": {
  788. "ECALEvalTest:10": true
  789. },
  790. "code": "log(\"a exit\")",
  791. "threads": {
  792. "1": {
  793. "callStack": [
  794. "fa(1) (ECALEvalTest:21)"
  795. ],
  796. "error": null,
  797. "threadRunning": false
  798. }
  799. },
  800. "vs": {
  801. "a": 1,
  802. "x": 1
  803. }
  804. }` {
  805. t.Error("Unexpected state:", state)
  806. return
  807. }
  808. // Set a new breakpoint
  809. _, err = testDebugger.HandleInput("break ECALEvalTest:28")
  810. errorutil.AssertOk(err)
  811. _, err = testDebugger.HandleInput(fmt.Sprintf("cont %v Resume", tid))
  812. errorutil.AssertOk(err)
  813. tid = waitForThreadSuspension(t)
  814. if state := getDebuggerState(tid, t); state != `{
  815. "breakpoints": {
  816. "ECALEvalTest:10": true,
  817. "ECALEvalTest:28": true
  818. },
  819. "code": "d(d())",
  820. "threads": {
  821. "1": {
  822. "callStack": [],
  823. "error": null,
  824. "threadRunning": false
  825. }
  826. },
  827. "vs": {
  828. "d": "ecal.function: d (Line 25, Pos 1)",
  829. "e": "ecal.function: e (Line 22, Pos 1)",
  830. "fa": "ecal.function: fa (Line 3, Pos 1)",
  831. "fb": "ecal.function: fb (Line 9, Pos 1)",
  832. "fc": "ecal.function: fc (Line 16, Pos 1)"
  833. }
  834. }` {
  835. t.Error("Unexpected state:", state)
  836. return
  837. }
  838. // Normal step over
  839. _, err = testDebugger.HandleInput(fmt.Sprintf("cont %v stepover", tid))
  840. errorutil.AssertOk(err)
  841. tid = waitForThreadSuspension(t)
  842. if state := getDebuggerState(tid, t); state != `{
  843. "breakpoints": {
  844. "ECALEvalTest:10": true,
  845. "ECALEvalTest:28": true
  846. },
  847. "code": "d(d())",
  848. "threads": {
  849. "1": {
  850. "callStack": [],
  851. "error": null,
  852. "threadRunning": false
  853. }
  854. },
  855. "vs": {
  856. "d": "ecal.function: d (Line 25, Pos 1)",
  857. "e": "ecal.function: e (Line 22, Pos 1)",
  858. "fa": "ecal.function: fa (Line 3, Pos 1)",
  859. "fb": "ecal.function: fb (Line 9, Pos 1)",
  860. "fc": "ecal.function: fc (Line 16, Pos 1)"
  861. }
  862. }` {
  863. t.Error("Unexpected state:", state)
  864. return
  865. }
  866. if _, err := testDebugger.HandleInput(fmt.Sprintf("cont %v stepover", tid)); err != nil {
  867. t.Error("Unexpected result:", err)
  868. return
  869. }
  870. tid = waitForThreadSuspension(t)
  871. if state := getDebuggerState(tid, t); state != `{
  872. "breakpoints": {
  873. "ECALEvalTest:10": true,
  874. "ECALEvalTest:28": true
  875. },
  876. "code": "log(\"finish\")",
  877. "threads": {
  878. "1": {
  879. "callStack": [],
  880. "error": null,
  881. "threadRunning": false
  882. }
  883. },
  884. "vs": {
  885. "d": "ecal.function: d (Line 25, Pos 1)",
  886. "e": "ecal.function: e (Line 22, Pos 1)",
  887. "fa": "ecal.function: fa (Line 3, Pos 1)",
  888. "fb": "ecal.function: fb (Line 9, Pos 1)",
  889. "fc": "ecal.function: fc (Line 16, Pos 1)"
  890. }
  891. }` {
  892. t.Error("Unexpected state:", state)
  893. return
  894. }
  895. // Continue until the end
  896. _, err = testDebugger.HandleInput(fmt.Sprintf("cont %v Resume", tid))
  897. errorutil.AssertOk(err)
  898. wg.Wait()
  899. if err != nil || testlogger.String() != `
  900. start
  901. a enter
  902. b enter
  903. c enter
  904. c exit
  905. c enter
  906. c exit
  907. c enter
  908. c exit
  909. b exit
  910. a exit
  911. e()
  912. e()
  913. finish`[1:] {
  914. t.Error("Unexpected result:", testlogger.String(), err)
  915. return
  916. }
  917. }
  918. func TestStepDebuggingWithImport(t *testing.T) {
  919. var err error
  920. defer func() {
  921. testDebugger = nil
  922. }()
  923. testDebugger = NewECALDebugger(nil)
  924. il := &util.MemoryImportLocator{Files: make(map[string]string)}
  925. il.Files["foo/bar"] = `
  926. func myfunc(n) {
  927. if (n <= 1) {
  928. return n
  929. }
  930. n := n + 1
  931. return n
  932. }
  933. `
  934. code := `
  935. a := 1
  936. import "foo/bar" as foobar
  937. log("start")
  938. a := foobar.myfunc(a)
  939. log("finish: ", a)
  940. `
  941. if _, err = testDebugger.HandleInput("break ECALEvalTest:4"); err != nil {
  942. t.Error("Unexpected result:", err)
  943. return
  944. }
  945. if _, err = testDebugger.HandleInput("break foo/bar:4"); err != nil {
  946. t.Error("Unexpected result:", err)
  947. return
  948. }
  949. wg := &sync.WaitGroup{}
  950. wg.Add(1)
  951. go func() {
  952. _, err = UnitTestEvalAndASTAndImport(code, nil, "", il)
  953. if err != nil {
  954. t.Error(err)
  955. }
  956. wg.Done()
  957. }()
  958. tid := waitForThreadSuspension(t)
  959. if state := getDebuggerState(tid, t); state != `{
  960. "breakpoints": {
  961. "ECALEvalTest:4": true,
  962. "foo/bar:4": true
  963. },
  964. "code": "log(\"start\")",
  965. "threads": {
  966. "1": {
  967. "callStack": [],
  968. "error": null,
  969. "threadRunning": false
  970. }
  971. },
  972. "vs": {
  973. "a": 1,
  974. "foobar": {
  975. "myfunc": "ecal.function: myfunc (Line 2, Pos 1)"
  976. }
  977. }
  978. }` {
  979. t.Error("Unexpected state:", state)
  980. return
  981. }
  982. // Resume execution
  983. if _, err := testDebugger.HandleInput(fmt.Sprintf("cont %v resume", tid)); err != nil {
  984. t.Error("Unexpected result:", err)
  985. return
  986. }
  987. tid = waitForThreadSuspension(t)
  988. if state := getDebuggerState(tid, t); state != `{
  989. "breakpoints": {
  990. "ECALEvalTest:4": true,
  991. "foo/bar:4": true
  992. },
  993. "code": "return n",
  994. "threads": {
  995. "1": {
  996. "callStack": [
  997. "myfunc(a) (ECALEvalTest:5)"
  998. ],
  999. "error": null,
  1000. "threadRunning": false
  1001. }
  1002. },
  1003. "vs": {
  1004. "n": 1
  1005. }
  1006. }` {
  1007. t.Error("Unexpected state:", state)
  1008. return
  1009. }
  1010. // Continue until the end
  1011. if _, err := testDebugger.HandleInput(fmt.Sprintf("cont %v Resume", tid)); err != nil {
  1012. t.Error("Unexpected result:", err)
  1013. return
  1014. }
  1015. wg.Wait()
  1016. if err != nil || testlogger.String() != `
  1017. start
  1018. finish: 1`[1:] {
  1019. t.Error("Unexpected result:", testlogger.String(), err)
  1020. return
  1021. }
  1022. }
  1023. func getDebuggerState(tid uint64, t *testing.T) string {
  1024. out, err := testDebugger.HandleInput(fmt.Sprintf("status"))
  1025. if err != nil {
  1026. t.Error(err)
  1027. return ""
  1028. }
  1029. outMap := out.(map[string]interface{})
  1030. out, err = testDebugger.HandleInput(fmt.Sprintf("describe %v", tid))
  1031. if err != nil {
  1032. t.Error(err)
  1033. return ""
  1034. }
  1035. outMap2 := out.(map[string]interface{})
  1036. outMap["vs"] = outMap2["vs"]
  1037. outMap["code"] = outMap2["code"]
  1038. delete(outMap, "breakonstart")
  1039. delete(outMap, "sources")
  1040. outBytes, _ := json.MarshalIndent(outMap, "", " ")
  1041. return string(outBytes)
  1042. }
  1043. func TestInjectAndExtractDebugging(t *testing.T) {
  1044. var err error
  1045. defer func() {
  1046. testDebugger = nil
  1047. }()
  1048. vs := scope.NewScope(scope.GlobalScope)
  1049. testDebugger = NewECALDebugger(vs)
  1050. if _, err = testDebugger.HandleInput("break ECALEvalTest:5"); err != nil {
  1051. t.Error("Unexpected result:", err)
  1052. return
  1053. }
  1054. wg := &sync.WaitGroup{}
  1055. wg.Add(1)
  1056. go func() {
  1057. _, err = UnitTestEval(`
  1058. b := 49
  1059. func myfunc() {
  1060. a := 56
  1061. log("test2 a=", a)
  1062. }
  1063. log("test1")
  1064. myfunc()
  1065. log("test3 b=", b)
  1066. `, vs)
  1067. if err != nil {
  1068. t.Error(err)
  1069. }
  1070. wg.Done()
  1071. }()
  1072. tid := waitForThreadSuspension(t)
  1073. out, err := testDebugger.HandleInput(fmt.Sprintf("status"))
  1074. outBytes, _ := json.MarshalIndent(out, "", " ")
  1075. outString := string(outBytes)
  1076. if err != nil || outString != `{
  1077. "breakonstart": false,
  1078. "breakpoints": {
  1079. "ECALEvalTest:5": true
  1080. },
  1081. "sources": [
  1082. "ECALEvalTest"
  1083. ],
  1084. "threads": {
  1085. "1": {
  1086. "callStack": [
  1087. "myfunc() (ECALEvalTest:8)"
  1088. ],
  1089. "error": null,
  1090. "threadRunning": false
  1091. }
  1092. }
  1093. }` {
  1094. t.Error("Unexpected result:", outString, err)
  1095. return
  1096. }
  1097. out, err = testDebugger.HandleInput(fmt.Sprintf("describe %v", tid))
  1098. outBytes, _ = json.MarshalIndent(out, "", " ")
  1099. outString = string(outBytes)
  1100. if err != nil || outString != `{
  1101. "callStack": [
  1102. "myfunc() (ECALEvalTest:8)"
  1103. ],
  1104. "callStackNode": [
  1105. {
  1106. "allowescapes": false,
  1107. "children": [
  1108. {
  1109. "name": "funccall"
  1110. }
  1111. ],
  1112. "id": 7,
  1113. "identifier": true,
  1114. "line": 8,
  1115. "linepos": 1,
  1116. "name": "identifier",
  1117. "pos": 69,
  1118. "source": "ECALEvalTest",
  1119. "value": "myfunc"
  1120. }
  1121. ],
  1122. "callStackVsSnapshot": [
  1123. {
  1124. "b": 49,
  1125. "myfunc": "ecal.function: myfunc (Line 3, Pos 1)"
  1126. }
  1127. ],
  1128. "callStackVsSnapshotGlobal": [
  1129. {
  1130. "b": 49,
  1131. "myfunc": "ecal.function: myfunc (Line 3, Pos 1)"
  1132. }
  1133. ],
  1134. "code": "log(\"test2 a=\", a)",
  1135. "error": null,
  1136. "node": {
  1137. "allowescapes": false,
  1138. "children": [
  1139. {
  1140. "children": [
  1141. {
  1142. "allowescapes": true,
  1143. "id": 5,
  1144. "identifier": false,
  1145. "line": 5,
  1146. "linepos": 6,
  1147. "name": "string",
  1148. "pos": 39,
  1149. "source": "ECALEvalTest",
  1150. "value": "test2 a="
  1151. },
  1152. {
  1153. "allowescapes": false,
  1154. "id": 7,
  1155. "identifier": true,
  1156. "line": 5,
  1157. "linepos": 18,
  1158. "name": "identifier",
  1159. "pos": 51,
  1160. "source": "ECALEvalTest",
  1161. "value": "a"
  1162. }
  1163. ],
  1164. "name": "funccall"
  1165. }
  1166. ],
  1167. "id": 7,
  1168. "identifier": true,
  1169. "line": 5,
  1170. "linepos": 2,
  1171. "name": "identifier",
  1172. "pos": 35,
  1173. "source": "ECALEvalTest",
  1174. "value": "log"
  1175. },
  1176. "threadRunning": false,
  1177. "vs": {
  1178. "a": 56
  1179. },
  1180. "vsGlobal": {
  1181. "b": 49,
  1182. "myfunc": "ecal.function: myfunc (Line 3, Pos 1)"
  1183. }
  1184. }` {
  1185. t.Error("Unexpected result:", outString, err)
  1186. return
  1187. }
  1188. if _, err := testDebugger.HandleInput(fmt.Sprintf("extract %v a foo", tid)); err != nil {
  1189. t.Error("Unexpected result:", err)
  1190. return
  1191. }
  1192. if _, err := testDebugger.HandleInput(fmt.Sprintf("inject %v a x := b + 1; x", tid)); err != nil {
  1193. t.Error("Unexpected result:", err)
  1194. return
  1195. }
  1196. // Continue until the end
  1197. if _, err := testDebugger.HandleInput(fmt.Sprintf("cont %v Resume", tid)); err != nil {
  1198. t.Error("Unexpected result:", err)
  1199. return
  1200. }
  1201. wg.Wait()
  1202. if vs.String() != `
  1203. GlobalScope {
  1204. b (float64) : 49
  1205. foo (float64) : 56
  1206. myfunc (*interpreter.function) : ecal.function: myfunc (Line 3, Pos 1)
  1207. }`[1:] {
  1208. t.Error("Unexpected result:", vs.String(), err)
  1209. return
  1210. }
  1211. if testlogger.String() != `
  1212. test1
  1213. test2 a=50
  1214. test3 b=49`[1:] {
  1215. t.Error("Unexpected result:", testlogger.String(), err)
  1216. return
  1217. }
  1218. }
  1219. func TestSimpleStacktrace(t *testing.T) {
  1220. res, err := UnitTestEval(`
  1221. func a() {
  1222. b()
  1223. }
  1224. func b() {
  1225. c()
  1226. }
  1227. func c() {
  1228. raise("testerror")
  1229. }
  1230. a()
  1231. `, nil)
  1232. if err == nil {
  1233. t.Error("Unexpected result: ", res, err)
  1234. return
  1235. }
  1236. ss := err.(util.TraceableRuntimeError)
  1237. if out := fmt.Sprintf("%v\n %v", err.Error(), strings.Join(ss.GetTraceString(), "\n ")); out != `
  1238. ECAL error in ECALTestRuntime (ECALEvalTest): testerror () (Line:9 Pos:2)
  1239. raise("testerror") (ECALEvalTest:9)
  1240. c() (ECALEvalTest:6)
  1241. b() (ECALEvalTest:3)
  1242. a() (ECALEvalTest:11)`[1:] {
  1243. t.Error("Unexpected output:", out)
  1244. return
  1245. }
  1246. }
  1247. func TestDebugDocstrings(t *testing.T) {
  1248. for k, v := range DebugCommandsMap {
  1249. if res := v.DocString(); res == "" {
  1250. t.Error("Docstring missing for ", k)
  1251. return
  1252. }
  1253. }
  1254. }
  1255. func TestDebuggingErrorInput(t *testing.T) {
  1256. var err error
  1257. defer func() {
  1258. testDebugger = nil
  1259. }()
  1260. vs := scope.NewScope(scope.GlobalScope)
  1261. testDebugger = NewECALDebugger(vs)
  1262. if _, err = testDebugger.HandleInput("uuu"); err.Error() != `Unknown command: uuu` {
  1263. t.Error("Unexpected result:", err)
  1264. return
  1265. }
  1266. if _, err = testDebugger.HandleInput("break"); err.Error() != `Need a break target (<source>:<line>) as first parameter` {
  1267. t.Error("Unexpected result:", err)
  1268. return
  1269. }
  1270. if _, err = testDebugger.HandleInput("break foo"); err.Error() != `Invalid break target - should be <source>:<line>` {
  1271. t.Error("Unexpected result:", err)
  1272. return
  1273. }
  1274. if _, err = testDebugger.HandleInput("rmbreak"); err.Error() != `Need a break target (<source>[:<line>]) as first parameter` {
  1275. t.Error("Unexpected result:", err)
  1276. return
  1277. }
  1278. if _, err = testDebugger.HandleInput("disablebreak"); err.Error() != `Need a break target (<source>:<line>) as first parameter` {
  1279. t.Error("Unexpected result:", err)
  1280. return
  1281. }
  1282. if _, err = testDebugger.HandleInput("disablebreak foo"); err.Error() != `Invalid break target - should be <source>:<line>` {
  1283. t.Error("Unexpected result:", err)
  1284. return
  1285. }
  1286. if _, err = testDebugger.HandleInput("break ECALEvalTest:3"); err != nil {
  1287. t.Error("Unexpected result:", err)
  1288. return
  1289. }
  1290. wg := &sync.WaitGroup{}
  1291. wg.Add(1)
  1292. go func() {
  1293. _, err = UnitTestEval(`
  1294. a:=1
  1295. log("test1")
  1296. log("test2")
  1297. log("test3")
  1298. `, vs)
  1299. if err != nil {
  1300. t.Error(err)
  1301. }
  1302. wg.Done()
  1303. }()
  1304. tid := waitForThreadSuspension(t)
  1305. out, err := testDebugger.HandleInput(fmt.Sprintf("status"))
  1306. outBytes, _ := json.MarshalIndent(out, "", " ")
  1307. outString := string(outBytes)
  1308. if err != nil || outString != `{
  1309. "breakonstart": false,
  1310. "breakpoints": {
  1311. "ECALEvalTest:3": true
  1312. },
  1313. "sources": [
  1314. "ECALEvalTest"
  1315. ],
  1316. "threads": {
  1317. "1": {
  1318. "callStack": [],
  1319. "error": null,
  1320. "threadRunning": false
  1321. }
  1322. }
  1323. }` {
  1324. t.Error("Unexpected result:", outString, err)
  1325. return
  1326. }
  1327. if _, err = testDebugger.HandleInput(fmt.Sprintf("extract %v foo foo", tid)); err.Error() != `No such value foo` {
  1328. t.Error("Unexpected result:", err)
  1329. return
  1330. }
  1331. }
  1332. func TestDebuggingErrorInput2(t *testing.T) {
  1333. var err error
  1334. tid := 1
  1335. defer func() {
  1336. testDebugger = nil
  1337. }()
  1338. vs := scope.NewScope(scope.GlobalScope)
  1339. testDebugger = NewECALDebugger(vs)
  1340. if _, err = testDebugger.HandleInput("cont foo"); err.Error() != `Need a thread ID and a command Resume, StepIn, StepOver or StepOut` {
  1341. t.Error("Unexpected result:", err)
  1342. return
  1343. }
  1344. if _, err = testDebugger.HandleInput("cont foo bar"); err.Error() != `Parameter 1 should be a number` {
  1345. t.Error("Unexpected result:", err)
  1346. return
  1347. }
  1348. if _, err = testDebugger.HandleInput("cont 99 bar"); err.Error() != `Invalid command bar - must be resume, stepin, stepover or stepout` {
  1349. t.Error("Unexpected result:", err)
  1350. return
  1351. }
  1352. if _, err = testDebugger.HandleInput("describe"); err.Error() != `Need a thread ID` {
  1353. t.Error("Unexpected result:", err)
  1354. return
  1355. }
  1356. if _, err = testDebugger.HandleInput(fmt.Sprintf("extract %v foo", tid)); err.Error() != `Need a thread ID, a variable name and a destination variable name` {
  1357. t.Error("Unexpected result:", err)
  1358. return
  1359. }
  1360. if _, err = testDebugger.HandleInput(fmt.Sprintf("extract %v _foo foo", tid)); err.Error() != `Variable names may only contain [a-zA-Z] and [a-zA-Z0-9] from the second character` {
  1361. t.Error("Unexpected result:", err)
  1362. return
  1363. }
  1364. if _, err = testDebugger.HandleInput(fmt.Sprintf("inject %v", tid)); err.Error() != `Need a thread ID, a variable name and an expression` {
  1365. t.Error("Unexpected result:", err)
  1366. return
  1367. }
  1368. testDebugger.(*ecalDebugger).globalScope = nil
  1369. if _, err = testDebugger.HandleInput(fmt.Sprintf("extract %v foo foo", tid)); err.Error() != `Cannot access global scope` {
  1370. t.Error("Unexpected result:", err)
  1371. return
  1372. }
  1373. if _, err = testDebugger.HandleInput(fmt.Sprintf("inject %v foo foo", tid)); err.Error() != `Cannot access global scope` {
  1374. t.Error("Unexpected result:", err)
  1375. return
  1376. }
  1377. }