【问题标题】:V8 debugger in Eclipse: Logic, or weirdest bug ever?Eclipse 中的 V8 调试器:逻辑,还是最奇怪的错误?
【发布时间】:2012-08-22 23:54:23
【问题描述】:

我正在编写一个 Node.js 应用程序,其中我使用字符串转换的整数作为键(例如“62616324573”)用数据填充 Object。对象总是将键 {key:} 存储为字符串,这与 javascript arrays 及其 [index] 的工作方式相比是理想的:

一个数组定义一百万次undefined,定义索引之间的每个索引一次。

但是,我发现我无法正确调试我的新对象,因为Eclipse 中的Variables 面板显示Failed to read variables。在内部,它们似乎工作正常。

取以下代码:

var util = require('util');
util.debug('Run this with --debug-brk=port, and press Resume (F8) to break at the breakpoint below.');

var debugMe = {
    "1000000000" : {
//  "2011743958" : {
        "some" : 1234,
        "random" : true,
        "data" : undefined
    },
//  "1000000001" : {
//  "8302611133" : {
    "3302611133" : {
        "some" : 12345678,
        "random" : false,
        "data" : null
    }
};

util.debug(JSON.stringify(debugMe)); // Look, it prints fine in all cases. This is internal javascript code.
util.debug('...');
util.inspect(debugMe); // And now it doesn't. This is V8 debugging code.

var breakpoint_here = true; // Set breakpoint here!

// hohoho

breakpoint_here 设置断点并使用即时中断调试器运行它,例如node --debug-brk=5858 debugtest.js。按resume 从第 1 行跳转到断点。转到您的Variables 面板并尝试检查debugMe:面板将崩溃。

使用 10..00 和 10..01 再试一次。没问题。除了,从它的写入方式来看,这些数字似乎被解析为数组索引 (!)。

debugMe ->
  [1000000000] -> [Object]
  [1000000001] -> [Object]

现在试试 10..10 和 83..02。突然间,83..33 是普通的JSON key 而不是数组索引,但 10..00 仍然是数组索引。 (?)

debugMe ->
  8302611133 ->  [Object]
  [1000000000] -> [Object]

现在尝试 10..00 和 33..33,Variables 窗口将再次崩溃。这是我所期望的:

debugMe ->
  1000000000 -> [Object]
  3302611133 -> [Object]

这就是我猜测正在发生的事情,尽管在调试仍然合作的对象时您实际上看不到它:

debugMe ->
  [1000000000] -> [Object]
  [1000000001] -> undefined
  // (...) // debugger memory fills up
  [3302611132] -> undefined
  [3302611133] -> [Object]

我猜测的问题是本例中的数字都是数组索引,相差太大,因为调试器会记住2302611133次undefined,这个问题应该只有在使用array时才会出现而不是 JSON object

  • 为什么有些数字被当作键(字符串)而另一些被当作索引?
  • 为什么某些索引组合在调试器中可以工作,而其他的却不行?
  • 在我不知道的情况下,“百万次未定义”问题是否也发生在对象上?

让我回顾一下:

  • 字符串转换整数 'int' 的细微差别似乎可以正常工作,但在调试器中它们变成 [indices]
  • 在密钥中高达约十亿的巨大差异不起作用,Variables 窗口崩溃。没有控制台输出。
  • 更大的差异再次起作用,但有些成为[索引],而另一些则保持“关键”。

因为我必须进行手动崩溃测试,所以我花了很长时间才发现问题出在数字上,而不是对象本身的内容上。很难想象问题只影响调试器而不影响应用程序本身,因为它是相同的 (V8) 引擎。我希望有人能指出我遗漏的所有事实和变量。

-更新-

似乎没有人知道这件事。未知的逻辑,也不是已知的错误。我在 Eclipse WDT 上 filed a bug,虽然我不确定这是行为的根源。

【问题讨论】:

  • 对象键是字符串,而不是数字。您会看到 V8 有时将它们转换为字符串以用作键,这表明它使用启发式方法来决定是最好将数字用作数组中的索引还是将其转换为字符串以用作对象中的键。您是否尝试过将数字转换为字符串 before 使用它们?这应该迫使 V8 使用一个对象......不过我不知道 Eclipse 有什么问题。
  • 我使用双引号语法(“1000000000”),这意味着(字符串)。上面的示例是重新创建此行为所需的全部内容,我使用 (Int) 代替 (String) 没有额外的步骤。
  • 就像你说的,对象键是字符串。您启发我认为调试器错误地将字符串解析为数字,但仅限于某些值。好像有一个神奇的数字,就像 MSX-Basic 上的 65535 一样,超过它的整数解析不再发生。
  • 对不起,我关注的是你的调试输出而不是你的代码,这让我认为它与 Integers as Strings 有关。还有一点需要注意:inspect 是 NodeJS 的一部分,而不是 V8。
  • 没问题,感谢您和我一起思考。至于你的另一点,NodeJS 是基于 V8 javascript 引擎构建的,调试器由 V8 Chrome 开发工具(用于 Eclipse)提供。所以我认为问题出在 V8 和/或 Eclipse。

标签: eclipse node.js v8 javascript-debugger


【解决方案1】:

虽然当您的节点应用程序使用大量基于整数的查找时可能会引入大量小重写,但最简单的解决方法是在您的代码中引入potatoesalad

例如

var debugMe = {
    "potatoesalad1000000000" : {},
    "potatoesalad3302611133" : {}
};

现在调试器按预期工作,您至少可以在我们等待知识渊博的人解释此现象的同时调试您的程序。

【讨论】:

    【解决方案2】:

    在这里提问,

    简短:
    这是一个错误。使用potatoesalad 作为解决方法。 (见其他答案)

    更长的:

    缺乏回应让我相信没有逻辑,这实际上是一个错误。

    一开始我并不清楚bug的来源(Eclipse/WDT/Node/V8),所以我提交了bugreport at Eclipse

    错误原来是not_eclipse,所以我在 Chrome 开发工具项目中re-filed the bugreport

    这个bug被接受了,结果发现是两个bug:
    Issue 76
    Issue 77

    【讨论】:

      猜你喜欢
      • 2021-06-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-28
      • 1970-01-01
      • 2022-10-23
      • 2017-06-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多