Changeset 2690


Ignore:
Timestamp:
5/25/2012 2:14:42 AM (3 years ago)
Author:
lowjoel
Message:

Factorise the QueryStatus? function to allow us to determine the most likely report matching a given set of exceptions and its stack traces. The output is backwards-compatible with the old 6.1 clients since no XML attributes are removed, only an extra id attribute is returned, indicating the most likely report ID.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/website/scripts/blackbox/upload.php

    r2689 r2690  
    3131} 
    3232 
     33function GetExceptionIDFromExceptionInfo($exception, $exceptionDepth) 
     34{ 
     35    $pdo = new Database(); 
     36    $stackFrames = ''; 
     37    foreach ($exception as $stackIndex => $stackFrame) 
     38    { 
     39        //Ignore the exception key; that stores the exception type. 
     40        if ($stackIndex == 'exception') 
     41            continue; 
     42 
     43        $stackFrames .= sprintf('(StackFrameIndex=%d AND Function=%s) OR ', 
     44            $stackIndex, $pdo->quote(GetFunctionNameFromStackTrace($stackFrame))); 
     45    } 
     46 
     47    if (empty($stackFrames)) 
     48        return null; 
     49 
     50    //Query for the list of exceptions containing the given functions 
     51    $statement = $pdo->prepare(sprintf('SELECT DISTINCT(blackbox_exceptions.ID) AS ExceptionID FROM blackbox_stackframes 
     52        INNER JOIN blackbox_exceptions ON blackbox_stackframes.ExceptionID=blackbox_exceptions.ID 
     53        WHERE (%s) AND ExceptionDepth=? AND ExceptionType=?', 
     54        substr($stackFrames, 0, strlen($stackFrames) - 4))); 
     55    $statement->bindParam(1, $exceptionDepth); 
     56    $statement->bindParam(2, $exception['exception']); 
     57    $statement->execute(); 
     58 
     59    if ($statement->rowCount() == 0) 
     60        return false; 
     61    $row = $statement->fetch(); 
     62    return $row['ExceptionID']; 
     63} 
     64 
    3365function QueryStatus($stackTrace) 
    3466{ 
    35     //Check that a similar stack trace hasn't been uploaded. 
    3667    $status = 'exists'; 
     68    $reportID = false; 
     69    $exceptionIDs = array(); 
    3770    $pdo = new Database(); 
     71     
    3872    foreach ($stackTrace as $exceptionDepth => $exception) 
    3973    { 
    40         if ($status != 'exists') 
     74        $exceptionID = GetExceptionIDFromExceptionInfo($exception, $exceptionDepth); 
     75        if ($exceptionID === null) 
     76            continue; 
     77        else if ($exceptionID === false) 
     78        { 
     79            $status = 'new'; 
    4180            break; 
    42  
    43         $stackFrames = ''; 
    44         foreach ($exception as $stackIndex => $stackFrame) 
    45         { 
    46             //Ignore the exception key; that stores the exception type. 
    47             if ($stackIndex == 'exception') 
    48                 continue; 
    49  
    50             $stackFrames .= sprintf('(StackFrameIndex=%d AND Function=%s) OR ', 
    51                 $stackIndex, $pdo->quote(GetFunctionNameFromStackTrace($stackFrame))); 
    52         } 
    53          
    54         if (empty($stackFrames)) 
    55             continue; 
    56          
    57         //Query for the list of exceptions containing the given functions 
    58         $statement = $pdo->prepare(sprintf('SELECT DISTINCT(blackbox_exceptions.ID) FROM blackbox_stackframes 
    59             INNER JOIN blackbox_exceptions ON blackbox_stackframes.ExceptionID=blackbox_exceptions.ID 
    60             WHERE (%s) AND ExceptionDepth=? AND ExceptionType=?', 
    61             substr($stackFrames, 0, strlen($stackFrames) - 4))); 
    62         $statement->bindParam(1, $exceptionDepth); 
    63         $statement->bindParam(2, $exception['exception']); 
    64         $statement->execute(); 
    65  
    66         if ($statement->rowCount() == 0) 
    67             $status = 'new'; 
    68     } 
    69      
     81        } 
     82        else 
     83            //Store the current exception ID on the stack 
     84            array_push($exceptionIDs, $exceptionID); 
     85    } 
     86 
    7087    header('Content-Type: application/xml'); 
     88     
     89    //If this is an existing exception, try to find the most similar report. 
     90    if ($status == 'exists' && count($exceptionIDs) > 0) 
     91    { 
     92        $ids = implode(', ', $exceptionIDs); 
     93        $result = $pdo->query(sprintf('SELECT ReportID, COUNT(ID) as Matches FROM blackbox_exceptions 
     94            WHERE ID IN (%s) GROUP BY ReportID ORDER BY Matches DESC', $ids)); 
     95        if ($result->rowCount() > 0) 
     96        { 
     97            $row = $result->fetch(); 
     98            $reportID = $row['ReportID']; 
     99 
     100            printf('<?xml version="1.0"?> 
     101<crashReport status="exists" id="%s" />', htmlspecialchars($status), $reportID); 
     102            return; 
     103        } 
     104    } 
     105 
     106    //Otherwise just return the status of the report. 
    71107    printf('<?xml version="1.0"?> 
    72108<crashReport status="%s" />', htmlspecialchars($status)); 
Note: See TracChangeset for help on using the changeset viewer.