Chinaunix首页 | 论坛 | 博客
  • 博客访问: 145764
  • 博文数量: 124
  • 博客积分: 70
  • 博客等级: 民兵
  • 技术积分: 1745
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-24 13:49
文章分类

全部博文(124)

文章存档

2011年(55)

2010年(14)

2009年(30)

2008年(25)

我的朋友

分类: WINDOWS

2011-09-15 10:56:44



曾经写了一篇简单的文章,讲述了qtwebkit中获取错误时候js的行号以及文件名的 http://blogold.chinaunix.net/u/18544/showart.php?id=2622370


但是经过一段时间的验证,发现这个还是有缺陷。


即当测试时候如果发现问题,就需要remote debug或者即使在本机也不是很方便,因此后来加了一些特别处理。

简单来说想在弹出那个shouldinterruptjs的dlg之前能够弹另外一个自定义对话框,而这个对话框能够显示出问题的行号,文件名。


所以做了如下一些修改。


1. 当然还是关闭jit,流氓关闭方法前面的文章也有。
2. 截获timeout的触发点,修改通知方式

    src\3rdparty\webkit\JavaScriptCore\interpreter\Interpreter.cpp
    #define CHECK_FOR_TIMEOUT() \
     if (!--tickCount) { \
-        if (globalData->timeoutChecker.didTimeOut(callFrame)) { \
+        if (globalData->timeoutChecker.didTimeOut(callFrame,vPC)) { \
             exceptionValue = jsNull(); \
             goto vm_throw; \
         } \

3. src\3rdparty\webkit\JavaScriptCore\runtime\JSGlobalObject.h

+ virtual void internalException(const char*) const { }

4. src\3rdparty\webkit\JavaScriptCore\runtime\TimeoutChecker.cpp

   +bool TimeoutChecker::didTimeOut(ExecState* exec,Instruction* vPC)
+{
+    unsigned currentTime = getCPUTime();
+    
+    if (!m_timeAtLastCheck) {
+        // Suspicious amount of looping in a script -- start timing it
+        m_timeAtLastCheck = currentTime;
+        return false;
+    }
+    
+    unsigned timeDiff = currentTime - m_timeAtLastCheck;
+    
+    if (timeDiff == 0)
+        timeDiff = 1;
+    
+    m_timeExecuting += timeDiff;
+    m_timeAtLastCheck = currentTime;
+    
+    // Adjust the tick threshold so we get the next checkTimeout call in the
+    // interval specified in intervalBetweenChecks.
+    m_ticksUntilNextCheck = static_cast((static_cast(intervalBetweenChecks) / timeDiff) * m_ticksUntilNextCheck);
+    // If the new threshold is 0 reset it to the default threshold. This can happen if the timeDiff is higher than the
+    // preferred script check time interval.
+    if (m_ticksUntilNextCheck == 0)
+        m_ticksUntilNextCheck = ticksUntilFirstCheck;
+    
+    if (m_timeoutInterval && m_timeExecuting > m_timeoutInterval) {
+ CodeBlock* codeBlock = exec->codeBlock();
+ int bytecodeOffset = vPC - exec->codeBlock()->instructions().begin();
+ int linenm = codeBlock->lineNumberForBytecodeOffset(exec, bytecodeOffset);
+        int sourceID = codeBlock->ownerExecutable()->sourceID();
+        const UString& strURL = codeBlock->ownerExecutable()->sourceURL();
+ const UString& strCode = UString(codeBlock->source()->data(),codeBlock->source()->length());
+
+ UString strSourceOffset = UString::from(codeBlock->sourceOffset());
+ UString strLineNum = UString::from(linenm);
+ UString strSourceID = UString::from(sourceID);
+
+ CString strMsg("linenum=");
+ strMsg += CString(strLineNum.ascii());
+ strMsg += ("\n");
+ strMsg += "offset=";
+ strMsg += CString(strSourceOffset.ascii());
+ //strMsg += ("\n");
+ //strMsg += "sourceid=";
+ //strMsg += CString(strSourceID.ascii());
+ strMsg += ("\n");
+ strMsg += "url=";
+ strMsg += CString(strURL.ascii());
+ strMsg += ("\n");
+ strMsg += "code=";
+ strMsg += CString(strCode.ascii());
+
+ exec->dynamicGlobalObject()->internalException(strMsg.c_str());
+ // endif
+        if (exec->dynamicGlobalObject()->shouldInterruptScript())
+            return true;
+        
+        reset();
+    }
+    
+    return false;
+}

5. src\3rdparty\webkit\WebCore\bindings\js\JSDOMWindowBase.cpp

   +void JSDOMWindowBase::internalException(const char* msg) const
+{
+    ASSERT(impl()->frame());
+    Page* page = impl()->frame()->page();
+
+    // See . We don't think that page can ever be NULL
+    // in this case, but if it is, we've gotten into a state where we may have
+    // hung the UI, with no way to ask the client whether to cancel execution.
+    // For now, our solution is just to cancel execution no matter what,
+    // ensuring that we never hang. We might want to consider other solutions
+    // if we discover problems with this one.
+    ASSERT(page);
+    if (!page)
+        return ;
+
+ return page->chrome()->runJavaScriptAlert(impl()->frame(),String(msg));
+}


这样当出现问题时候就会弹出文件,行号,偏移量。


这儿有个小插曲,上面红色部分代码还print了code,那么为什么呢?

当初首次修改的时候,发现如果发生问题的代码出现在一个html ref的js或者js ref的另外一个js时候,url 竟然是空的,行号是有的。

后来找来找去把这个code print出来即可,而且这个code本身最后还带有这个code是来自于哪个js文件的信息。


这样当出现问题时候,100%知道了是谁,即使碰到压缩过的js文件也可以通过offset找到是哪个地方。


阅读(302) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~